Короткий ответ
$? хранит код возврата последней выполненной команды (0 — успех, любое другое число от 1 до 255 — ошибка), и значение перезаписывается при выполнении любой следующей команды, поэтому проверять его нужно немедленно, не вставляя между вызовом и проверкой других команд.
Как это работает подробнее
каждая команда в Unix возвращает числовой код завершения процессу-родителю; shell сохраняет его в специальной переменной $? до следующей выполненной команды, включая встроенные команды вроде echo.
Пример кода
example-473.sh
#!/usr/bin/env bash
curl -fsS https://api.example.com/health
echo "Проверка выполнена"
if [ $? -ne 0 ]; then
echo "Ошибка: запрос упал"
fiЧто использовать на практике
- Рекомендация. в скриптах код возврата обычно проверяют через
if deploy; then report_success; else handle_error; fiилиcommand || handle_error, а не через отдельное чтение$?— это надёжнее и короче. Хранить$?в отдельной переменной (rc=$?) стоит, только если нужно использовать значение после нескольких последующих команд, например для логирования и очистки.
Подводные камни
- Ошибка. вызывать между командой и проверкой
$?любую другую команду (дажеecho "done"), из-за чего проверяется код возврата не той команды; игнорировать код возврата вовсе и полагаться только на текст вывода в логах.