Что означает set-e в сценарии bash?
Я изучаю содержание этого preinst нового пакета файл, который скрипт выполняет до распаковки пакета из архива Debian (.файл deb).
скрипт имеет следующий код:
мой первый запрос о строку:
Я думаю, что остальная часть скрипта довольно проста: он проверяет, выполняет ли менеджер пакетов Debian/Ubuntu операцию установки. Если это так, он проверяет, имеет ли мое приложение только что был установлен в системе. Если это так, скрипт печатает сообщение «MyApplicationName только что установлен» и заканчивается ( return 1 означает, что это заканчивается «ошибкой», не так ли?).
если пользователь просит систему пакетов Debian/Ubuntu установить мой пакет, скрипт также удаляет два каталога.
это правильно или я что-то пропустила?
4 ответов
но это считается плохой практикой некоторыми людьми (bash FAQ и такие, как люди, пишущие этот FAQ на irc freenode #bash), лучше использовать :
для выполнения do_something функция при возникновении ошибок.
по умолчанию состояние выхода конвейера является состоянием выхода последней команды конвейера, если только pipefail опция включена (она отключена неисполнение.)
если это так, состояние возврата конвейера последней (самой правой) команды для выхода с ненулевым статусом или нулем, если все команды завершаются успешно.
здесь onexit ваша функция, чтобы сделать что-то на выходе, как ниже, который печатает простой трассировка стека:
примеры
нулевое состояние пример:
отрицание примеров статуса:
В скрипте есть следующий код:
Мой первый вопрос касается строки:
Я думаю, что остальная часть скрипта довольно проста: он проверяет, выполняет ли менеджер пакетов Debian / Ubuntu операцию установки. Если это так, он проверяет, было ли мое приложение только что установлено в системе. Если это так, сценарий печатает сообщение «MyApplicationName только что установлено» и завершается ( return 1 означает, что это заканчивается «ошибкой», не так ли?).
Если пользователь просит систему пакетов Debian / Ubuntu установить мой пакет, сценарий также удаляет два каталога.
Это правильно или я что-то упускаю?
8 ответов
Но некоторые считают это плохой практикой (авторы bash FAQ и irc freenode #bash FAQ). Рекомендуется использовать:
Для запуска функции do_something при возникновении ошибок.
Теперь мы видим, что вместо этого сообщается об ошибке b.txt и не печатается привет.
Я считаю, что намерение состоит в том, чтобы рассматриваемый сценарий быстро завершился неудачей.
Теперь, чтобы понять это в контексте «сценария», используйте этот простой сценарий:
На практике это означает, что вы должны понимать, при каких условиях выполняемые вами команды могут возвращать ошибку, и обрабатывать каждую из этих ошибок явным образом.
Распространенные ошибки, например, diff (возвращает ошибку, если есть разница) и grep (возвращает ошибку, если совпадения нет). Вы можете избежать ошибок с явной обработкой:
(Обратите также внимание на то, как мы заботимся о включении имени текущего сценария в сообщение и написании диагностических сообщений для стандартной ошибки вместо стандартного вывода.)
Если явная обработка действительно не нужна или полезна, явно ничего не делайте:
(Использование команды no-op оболочки : немного неясно, но довольно часто встречается.)
Просто чтобы повторить,
Во многих ситуациях при защитном коде нужно особо остерегаться этого. Иногда вам нужно, например, пройдите через временный файл, чтобы вы могли видеть, успешно ли завершилась команда, которая произвела этот вывод, даже если идиома и удобство в противном случае побудили бы вас использовать конвейер оболочки.
Если да, то конвейер возвращает статус последней (самой правой) команды для выхода с ненулевым статусом или нулевым, если все команды завершаются успешно.
Примеры
Пример нулевого статуса:
Пример ненулевого статуса:
Примеры отрицательного статуса:
Тест с отключенным pipefail :
Тест с включенным pipefail :
Например, предположим, что у меня есть сценарий оболочки outer-test.sh :
Код для inner-test.sh :
Когда я запускаю outer-script.sh из командной строки, мой внешний сценарий завершается кодом выхода внутреннего сценария:
Что означает set-e в скрипте bash?
Я изучаю содержание этого preinst файл, который скрипт выполняет перед распаковкой этого пакета из архива Debian (.файл deb).
скрипт имеет следующий код:
мой первый запрос о строку:
Я думаю, что остальная часть скрипта довольно проста: он проверяет, выполняет ли менеджер пакетов Debian/Ubuntu операцию установки. Если это так, он проверяет, имеет ли мое приложение только что был установлен в системе. Если это так, скрипт печатает сообщение «MyApplicationName только что установлен» и заканчивается ( return 1 означает, что заканчивается «ошибка», не так ли?).
если пользователь просит систему пакетов Debian/Ubuntu установить мой пакет, скрипт также удаляет два каталога.
это правильно или я что-то пропустила?
4 ответов:
но это считается плохой практикой некоторыми людьми (bash FAQ и такие, как люди, пишущие этот FAQ на irc freenode #bash), лучше использовать:
для выполнения do_something функция, когда ошибки будут происходить.
по умолчанию состояние выхода конвейера является состоянием выхода последней команды в конвейере, если только pipefail опция включена (она отключена неисполнение.)
если это так, то конвейер возвращает статус последней (самой правой) команды для выхода с ненулевым статусом или нулем, если все команды завершаются успешно.
здесь onexit это ваша функция, чтобы сделать что-то на выходе, как ниже, который печатает простой трассировка стека:
примеры
нулевое состояние пример:
отрицание статуса примеры:
I’m studying the content of this preinst file that the script executes before that package is unpacked from its Debian archive (.deb) file.
The script has the following code:
My first query is about the line:
I think that the rest of the script is pretty simple: It checks whether the Debian/Ubuntu package manager is executing an install operation. If it is, it checks whether my application has just been installed on the system. If it has, the script prints the message «MyApplicationName is just installed» and ends ( return 1 mean that ends with an “error”, doesn’t it?).
If the user is asking the Debian/Ubuntu package system to install my package, the script also deletes two directories.
Is this right or am I missing something?
9 Answers 9
But it’s considered bad practice by some (bash FAQ and irc freenode #bash FAQ authors). It’s recommended to use:
to run do_something function when errors occur.
For example, suppose I have the shell script outer-test.sh :
The code for inner-test.sh is:
When I run outer-script.sh from the command line, my outer script terminates with the exit code of the inner script:
By default, the exit status of a pipeline is the exit status of the last command in the pipeline, unless the pipefail option is enabled (it’s disabled by default).
If so, the pipeline’s return status of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.
where onexit is your function to do something on exit, like below which is printing the simple stack trace:
Examples
Zero status example:
Non-zero status example:
Negating status examples:
Test with pipefail being disabled:
Test with pipefail being enabled:
What this means in practice is that you have to understand under what conditions the commands you run could return an error, and handle each of those errors explicitly.
Common gotchas are e.g. diff (returns an error when there is a difference) and grep (returns an error when there is no match). You can avoid the errors with explicit handling:
(Notice also how we take care to include the current script’s name in the message, and writing diagnostic messages to standard error instead of standard output.)
If no explicit handling is really necessary or useful, explicitly do nothing:
(The use of the shell’s : no-op command is slightly obscure, but fairly commonly seen.)
On the other hand, some commands don’t produce an error exit status when you’d want them to. Commonly problematic commands are find (exit status does not reflect whether files were actually found) and sed (exit status won’t reveal whether the script received any input or actually performed any commands successfully). A simple guard in some scenarios is to pipe to a command which does scream if there is no output:
Я изучаю содержимое этого файла preinst, который выполняется script, прежде чем этот пакет распакуется из файла архива Debian (.deb).
script имеет следующий код:
Мой первый запрос касается строки:
Я думаю, что остальная часть script довольно проста: она проверяет, выполняет ли диспетчер пакетов Debian/Ubuntu операцию установки. Если да, то проверяет, было ли мое приложение только что установлено в системе. Если он есть, script печатает сообщение «MyApplicationName только что установлен» и заканчивается ( return 1 означает, что он заканчивается «ошибкой», не так ли?).
Если пользователь запрашивает систему пакетов Debian/Ubuntu для установки моего пакета, script также удаляет два каталога.
Является ли это правильным или я что-то не хватает?
ОТВЕТЫ
Ответ 1
Но некоторые считают, что это плохая практика (bash FAQ и irc freenode #bash FAQ авторов). Рекомендуется использовать:
запускать функцию do_something при возникновении ошибок.
Ответ 2
Ответ 3
По умолчанию состояние выхода конвейера является состоянием выхода последней команды в конвейере, если только не включена опция pipefail (по умолчанию она отключена).
Если это так, конвейер возвращает состояние последней (самой правой) команды для выхода с ненулевым статусом или ноль, если все команды завершаются успешно.
Примеры
Пример нулевого статуса:
Пример ненулевого статуса:
Примеры отрицательного статуса:
Тест с отключенным pipefail :
Тест с включенным pipefail :
Ответ 4
Например, предположим, что у меня есть сценарий оболочки outer-test.sh :
Код для inner-test.sh :
Когда я запускаю outer-script.sh из командной строки, мой внешний скрипт завершается кодом выхода внутреннего скрипта:
Ответ 5
Теперь, чтобы понять это в контексте «скрипта», используйте этот простой скрипт:
Ответ 6
Ответ 7
На практике это означает, что вы должны понимать, при каких условиях выполняемые вами команды могут возвращать ошибку и явно обрабатывать каждую из этих ошибок.
Обычными getchas являются, например, diff (возвращает ошибку, когда есть разница) и grep (возвращает ошибку, когда нет совпадения). Вы можете избежать ошибок с явной обработкой:
(Обратите внимание также, как мы позаботимся о включении текущего имени сценария в сообщение и записи диагностических сообщений в стандартную ошибку вместо стандартного вывода.)
Если никакая явная обработка не является действительно необходимой или полезной, явно ничего не делать:
является сокращением для
Во многих ситуациях, это то, что нужно отдельно следить за кодированием в обороне. Иногда вам нужно, например, пройти через временный файл, чтобы вы могли увидеть, успешно ли завершилась команда, которая произвела этот вывод, даже если идиома и удобство в противном случае наводят вас на использование конвейера.




