Что означает `-eu` в `#!/bin/bash -eu` в начале сценария bash? (или любой из `-abefhkmnptuvxBCHP`)

Что означает euпосле #!/bin/bash -euв начале сценария bash?

Обычно я начинаю свои сценарии bash с этого hashbang/shebang:

#!/bin/bash

, но я только что наткнулся на один с

#!/bin/bash -eu

и понятия не имею, почему -eu] там. Чтение страниц man bash, кажется, не помогает мне, но, возможно, я что-то упускаю из виду.


Не дубликат:

Это не дубликат Правильное поведение ловушек EXIT и ERR при использовании `set -eu`.

Цитируя @ilkkachu в комментариях под этим вопросом, прямо обращаясь к этому:

...то, как -e и -u работают в отношении ловушек или чего-либо еще, совершенно не связано с тем, как они и другие одно- параметры символов могут быть заданы в командной строке.

Я согласен с этим. Это отдельные вопросы и ответы, за которыми стоят разные мотивы. Этот вопрос настолько отличается, что я никогда бы даже не подумал щелкнуть по нему, посмотрев его заголовок ИЛИ его описание, пытаясь понять ответ на мой собственный вопрос здесь, и ответы тоже сильно различаются.

-2
27.06.2020, 23:21
2 ответа

Это параметры сценария 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флаг, выполнение будет прекращено. Это может показаться удивительным, поскольку отсутствие выражения в файле на самом деле не является «ошибкой».

5
18.03.2021, 23:23

Это те же параметры, что и от -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указывает оболочке выйти, если команда завершается с ошибкой (, за исключением случаев, когда значение выхода проверяется каким-либо другим способом ). В некоторых случаях это можно использовать для прерывания сценария при ошибке без явного тестирования состояния каждой команды.

11
18.03.2021, 23:23

Теги

Похожие вопросы