В Bash и подобных оболочках echo $? печатает статус последней завершенной команды или конвейера переднего плана. Обычно 0 означает успех, ненулевое значение — другой результат, смысл которого зависит от команды. После успешного echo сам $? станет 0. Для конвейера по умолчанию берется статус последней команды; pipefail меняет это правило.
Что выводит команда echo $?
Что означает код завершения в Bash, почему его нужно читать сразу и как конвейер и настройка pipefail влияют на значение специального параметра $?.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
В Bash специальный параметр $? содержит статус последней завершенной команды или конвейера переднего плана. Команда echo $? подставляет текущее значение этого параметра и выводит его. Это код завершения, а не текст предыдущего вывода, не идентификатор процесса и не время выполнения.
Обычно 0 означает успешное завершение. Ненулевое значение обозначает иной результат, но его точный смысл нужно смотреть в документации конкретной команды. Например, отсутствие совпадений при поиске может иметь отдельный ненулевой статус и не означать поломку самой программы.
Простой пример для Bash:
false
echo "$?" # 1
echo "$?" # 0 после успешного предыдущего echo
Статус важно сохранить сразу, если между проверяемой командой и обработкой результата будут другие команды:
some_command
status=$?
echo "$status"
Здесь some_command — условное имя проверяемой команды. Вывод информационного сообщения перед сохранением статуса мог бы заменить интересующее значение статусом самого вывода.
Отдельный нюанс — конвейеры. По умолчанию статус first_command | second_command определяется последней командой. Поэтому сбой первой части может остаться незамеченным при проверке только $?. При включенном в Bash pipefail статусом станет статус крайней справа команды с ненулевым завершением, либо ноль, если все команды успешны. Для фонового процесса нужно дождаться его завершения через wait, а не считать статус запуска доказательством успешного выполнения всей работы.