Короткий ответ $? хранит код возврата последней выполненной команды (0 — успех, любое другое число от 1 до 255 — ошибка), и значение перезаписывается при выполнении любой следующей команды, поэтому проверять его нужно немедленно, не вставляя между вызовом и проверкой других команд. Как это работает подробнее каждая команда в Unix возвращает числовой код завершения процессу-родителю; shell сохраняет его в специальной переменной $? до следующей выполненной команды, включая встроенные команды вроде echo. Пример кода Что использовать на практике Рекомендация. в скриптах код возврата обычно проверяют через if deploy; then report_success; else handle_error; fi или command || handle_error, а не через отдельное чтение $? — это надёжнее и короче. Хранить $? в отдельной переменной (rc=$?) стоит, только если нужно использовать значение после нескольких последующих команд, например для логирования и очистки. Подводные камни Ошибка. вызывать между командой и проверкой $? любую другую команду (даже echo "done"), из-за чего