Что означает eu
после #!/bin/bash -eu
в начале сценария bash?
Обычно я начинаю свои сценарии bash с этого hashbang/shebang:
#!/bin/bash
, но я только что наткнулся на один с
#!/bin/bash -eu
и понятия не имею, почему -eu
] там. Чтение страниц man bash
, кажется, не помогает мне, но, возможно, я что-то упускаю из виду.
Не дубликат:
Это не дубликат Правильное поведение ловушек EXIT и ERR при использовании `set -eu`.
Цитируя @ilkkachu в комментариях под этим вопросом, прямо обращаясь к этому:
...то, как -e и -u работают в отношении ловушек или чего-либо еще, совершенно не связано с тем, как они и другие одно- параметры символов могут быть заданы в командной строке.
Я согласен с этим. Это отдельные вопросы и ответы, за которыми стоят разные мотивы. Этот вопрос настолько отличается, что я никогда бы даже не подумал щелкнуть по нему, посмотрев его заголовок ИЛИ его описание, пытаясь понять ответ на мой собственный вопрос здесь, и ответы тоже сильно различаются.
Это параметры сценария Bash, как описано во встроенной команде man bash
, set
.
В самом началеman bash
:
OPTIONS
All of the single-character shell options documented in the description of the set builtin command, including -o, can be used as options when the shell is invoked.
Итак, set
— это не отдельная команда, это встроенная оболочка. Вот почему вы не нашли справочной страницы с man set
. Вместо этого в руководстве по bash вы найдете раздел SHELL BUILTIN COMMANDS
. Будет встроенный set
, где это можно найти:
-e Exit immediately if a pipeline (which may consist of a single simple command), a list, or a compound command (see SHELL GRAMMAR above), exits with a non-zero status. (...)
-u Treat unset variables and parameters other than the special parameters "@" and "*" as an error when performing parameter expansion. If expansion is attempted on an unset variable or parameter, the shell prints an error message, and, if not interactive, exits with a non-zero status.
Итак, в моем примере ниже флаг -u
заставит скрипт выйти при первом эхе, так как notDeclared
не был объявлен. Точно так же он завершится на строке grep
из-за флага -e
, поскольку nonExistentFile
не существует, а grep, простая команда, завершается с ошибкой (не -нулевым статусом ).
#!/bin/bash -ue
echo "$notDeclared"
grep something nonExistentFile
echo "I am never going to be echoed..."
Если вы хотите, чтобы он закрывался на grep, то либо удалите -u
, либо переместите grep
наверх.
Примечание поgrep
:grep
завершается с ненулевым статусом -, если шаблон не найден в файле. Итак, в приведенном выше примере, если вы создали nonExistentFile
без строки something
в своем содержимом, grep
завершится с 1 (не -нулем )и, следовательно, из-за -e
флаг, выполнение будет прекращено. Это может показаться удивительным, поскольку отсутствие выражения в файле на самом деле не является «ошибкой».
Это те же параметры, что и от -e
и -u
до встроенной set
. Они также могут быть заданы в командной строке оболочки, а также в качестве аргументов командной строки из строки hashbang. (Но обратите внимание, напр. проблемы с Множественные аргументы в shebang)
В онлайн-руководстве в разделе "Вызов Bash" говорится, что
All of the single-character options used with the set builtin can be used as options when the shell is invoked.
Односимвольные параметры также явно перечислены в синопсисе вызова в онлайн-руководстве(bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o option]...
), но не на справочной странице.
set -u
указывает оболочке рассматривать расширение неустановленного параметра как ошибку, что помогает поймать, например. опечатки в именах переменных.
set -e
указывает оболочке выйти, если команда завершается с ошибкой (, за исключением случаев, когда значение выхода проверяется каким-либо другим способом ). В некоторых случаях это можно использовать для прерывания сценария при ошибке без явного тестирования состояния каждой команды.