Скрипт отвечает не только текстом. Число, с которым он завершился, говорит вызывающему, получилось ли.
Каждая программа, завершаясь, отдаёт число — код завершения: 0 — получилось, любое другое число — нет. Код последней команды bash хранит в $?, и echo $? сразу после команды его печатает. wc -l из прошлого шага вышел с кодом 1: один из трёх файлов он прочитать не смог.
Скрипт задаёт свой код командой exit N: она сразу завершает скрипт с кодом N. Что значит каждый код — договор автора скрипта. В этом уроке: 0 — готово, 1 — с файлом что-то не так, 2 — скрипт вызвали неправильно. Без exit код скрипта — код его последней команды.
Неправильный вызов — например, без аргументов, когда $# равно 0. Числа сравнивает проверка -eq: [ $# -eq 0 ]. Подсказку, как вызывать скрипт, печатают в поток ошибок: >&2 после echo отправляет вывод в поток 2, туда, где программы пишут ошибки. Так подсказка не попадёт в файл, куда направили результат скрипта.
Без аргументов скрипт выполняет echo "Usage: save.sh FILE" >&2 и exit 2. Ты запускаешь ./save.sh > out.txt. Что окажется в out.txt?
-
>направляет поток 1, а подсказка ушла в поток 2 через>&2— на экран.wc -c out.txtнапечатает 0. -
Код завершения не печатается в поток вывода: его хранит
$?. out.txt пустой —wc -c out.txtнапечатает 0. -
Оболочка создаёт out.txt ещё до запуска скрипта, как в уроке о потоках вывода.
ls -l out.txtпокажет пустой файл.
Оболочка создала out.txt до запуска скрипта, а > направил в него один поток 1. Подсказка ушла в поток 2 и осталась на экране, а echo $? после запуска напечатает 2.
Главное в шаге
-
Код завершения — ответ скрипта вызывающему:
exit Nзадаёт его,echo $?сразу после запуска показывает. -
Подсказку о неправильном вызове печатают в поток ошибок через
>&2и выходят с ненулевым кодом.