Большинство администраторов знают про
$?, но при работе с пайпами он может вводить в заблуждение.Посмотрим на пример:
grep ERROR app.log | sort | uniq
echo $?
Если пайп состоит из нескольких команд, $? покажет код возврата только последней из них.Если
grep завершился с ошибкой, а uniq отработал успешно, вы увидите:0
Хотя одна из команд фактически провалилась.▪️Решение - PIPESTATUS
После выполнения пайпа Bash сохраняет коды возврата всех его команд в массиве
PIPESTATUS:grep ERROR app.log | sort | uniq
echo "${PIPESTATUS[@]}"
Результат может выглядеть так:2 0 0
Здесь видно, что ошибка произошла именно в grep.▪️Проверка конкретного этапа
Можно обратиться к нужному элементу массива:
grep ERROR app.log | sort | uniq
echo "${PIPESTATUS[0]}"
Проверяем первую команду в цепочке.echo "${PIPESTATUS[1]}"
Проверяем вторую.▪️А что насчёт pipefail?
Многие включают:
set -o pipefail
Это полезно — теперь пайп вернёт ошибку, если упала любая команда внутри него.Но
pipefail не показывает, какой именно этап завершился неудачно.Для диагностики всё равно пригодится
PIPESTATUS.▪️Почему это важно
Если в скрипте есть длинные цепочки из
grep, awk, sed, jq, sort и других утилит, обычный $? может скрыть проблему. PIPESTATUS позволяет быстро понять, где именно произошёл сбой.BashTex 📱 #scripts #pipestatus