pipefail меняет код возврата конвейера. По умолчанию код берётся у последней команды, поэтому вот такая строка считается успешной, хотя первая половина легла:
curl -s https://example.org/spisok | grep -c 'tovar'
curl отвалился, grep честно посчитал ноль совпадений и вернул своё. Скрипт едет дальше с пустым списком. С pipefail код конвейера станет ненулевым, и вместе с set -e прогон остановится.
Дальше места, где оболочка кусается именно на длинных скриптах:
- пробелы в путях: любая переменная без кавычек разлетается на слова;
- пустая переменная в
rm -rf "$katalog"/ выносит корень целиком; - арифметика только целая, среднее время отклика посчитать нечем;
- разбор JSON без jq невозможен, а с jq вы уже пишете на втором языке внутри первого;
- функции возвращают только код, всё прочее едет через вывод и подстановку.
Поодиночке ничто из этого не смертельно. Вместе на трёхстах строках получается механизм, который держится на памяти автора.