Я не понимаю команду bash exec
. Я видел, как он используется внутри скриптов, чтобы перенаправить весь вывод в файл (как видно из этого ). Но я не понимаю, как это работает или что вообще делает. Я прочитал справочные страницы, но я их не понимаю.
107
exec
особый способ, который можно объяснить гораздо проще, я напишу ответ.Ответы:
man bash
говорит:Последние две строки - вот что важно: если вы запустите
exec
сам, без команды, это просто заставит перенаправления применяться к текущей оболочке. Вы, вероятно, знаете, что когда вы запускаетеcommand > file
, выводcommand
записываетсяfile
вместо вашего терминала (это называется перенаправлением ). Если вы запускаетеexec > file
вместо этого, то перенаправление применяется ко всей оболочке: любой вывод, произведенный оболочкой, записываетсяfile
вместо вашего терминала. Например здесьЯ сначала запускаю новую
bash
оболочку. Затем в этой новой оболочке я запускаюexec > file
, так что весь вывод перенаправляется вfile
. Действительно, после этого я бегу,date
но я не получаю вывод, потому что вывод перенаправлен вfile
. Затем я выхожу из своей оболочки (так что перенаправление больше не применяется), и я вижу, чтоfile
действительно содержит выводdate
команды, которую я выполнил ранее.источник
exec
служит также для замены текущего процесса оболочки командой, так что родительский процесс идет своим путем, а дочерний владеет pid. Это не только для перенаправления. Пожалуйста, добавьте эту информациюexec nginx <various nginx arguments>
. Это означает, что nginx принимает pid скрипта bash, и теперь nginx является основным запущенным процессом контейнера, а не скриптом. Я предполагаю, что это только для чистоты, если кто-то еще не знает более конкретную причину для этого?gnome-terminal
, который по крайней мере 14.04 имел скрипт-обертку для установки аргументов. И это их единственная цель, на самом деле - установить искусство и окружающую среду. Другой случай - очистить - сначала убить предыдущий процесс и запустить новыйexec
пример, аналогичныйnginx
примеру, приведенному @LukeGriffiths, - это~/.vnc/xstartup
сценарий, которыйvncserver
используется для настройки процесса сервера VNC, а затемexec gnome-session
илиexec startkde
и так далее.exec
в скрипте запуска контейнера состоит в том, что PID 1, ENTRYPOINT контейнера, имеет особое значение в Docker. Это основной процесс, который получает сигналы, и когда он существует, контейнер тоже выходит.exec
просто способ вывестиsh
из этой цепочки команд и сделать демон главным процессом контейнера.exec
это команда с двумя очень разными поведениями, в зависимости от того, используется ли с ней хотя бы один аргумент или вообще не используется ни один аргумент.Если передан хотя бы один аргумент, первый принимается за имя команды и
exec
пытается выполнить его как команду, передавая оставшиеся аргументы, если таковые имеются, этой команде и управляя перенаправлениями, если они есть.Если команда, переданная в качестве первого аргумента, не существует, текущая оболочка, а не только команда exec, завершается с ошибкой.
Если команда существует и является исполняемой, она заменяет текущую оболочку. Это означает, что если
exec
в скрипте появляется, инструкции, следующие за вызовом exec , никогда не будут выполнены (если только он неexec
находится в подоболочке).exec
никогда не вернется Оболочечные ловушки типа «EXIT» тоже не сработают.Если аргумент не передан,
exec
используется только для переопределения текущих дескрипторов файла оболочки. Оболочка продолжается послеexec
, в отличие от предыдущего случая, но вступают в силу стандартный ввод, вывод, ошибка или любой дескриптор файла, который был перенаправлен.Если некоторые из перенаправлений используют
/dev/null
, любой вход от него будет возвращать EOF, а любой выход для него будет отброшен.Вы можете закрыть файловые дескрипторы, используя в
-
качестве источника или места назначения, напримерexec <&-
. Последующее чтение или запись потерпит неудачу.Вот два примера:
Этот скрипт выведет «foo» в качестве команды cat, вместо того, чтобы ждать ввода пользователя, как это было бы в обычном случае, и получит свой ввод из файла / tmp / bar, который содержит foo.
Этот скрипт отобразит
4
(количество байтов в / tmp / bar) и сразу же завершится. Командаcat
не будет выполнена.источник
/dev/null
, поэтому запись по-прежнему успешна, а чтение возвращает EOF.close(2)
на FD вызовет системные вызовы чтения / записи, чтобы вернуть ошибки, и вы делаете это,exec 2>&-
например, с.exec 3</dev/null;
ls -l /proc/self/fd
обратите внимание, что fd 3 будет открыт только для чтения в / dev / null. Затем закройте его сноваexec 3<&-
, и вы увидите (ls -l /proc/$$/fd
снова), что у вашего процесса оболочки больше нет fd 3. (Закрытие стандартного вводаexec <&-
может быть полезно в сценариях, но в интерактивном режиме это выход из системы.)exec
использования текущего ответа с наибольшим количеством голосов говорит только об одном варианте использования, а другой ответ g_p говорит только о другом варианте использования. И этот ответ хорош и лаконичен / читабелен для такой сложной темы.Чтобы понять
exec
, нужно сначала понятьfork
. Я стараюсь быть коротким.Когда вы выходите на развилку дороги, у вас обычно есть два варианта. Программы Linux достигают этой развилки в дороге, когда сталкиваются с
fork()
системным вызовом.Обычные программы - это системные команды, которые существуют в скомпилированной форме в вашей системе. Когда такая программа выполняется, создается новый процесс. Этот дочерний процесс имеет ту же среду, что и его родительский процесс, отличается только идентификационный номер процесса. Эта процедура называется разветвлением .
exec
используется.exec
заменит содержимое текущего запущенного процесса информацией из двоичного файла программы.источник
exec
можно перенаправить вывод скрипта, как в ссылке, которую я разместил?В
bash
, если вы делаетеhelp exec
:Соответствующий бит:
exec
является встроенной оболочкой , которая является оболочкой, эквивалентнойexec
семейству системных вызовов, о которых говорит G_P (и чьи страницы управления, по-видимому, вы прочитали). Он имеет только обязательную функциональность POSIX, влияющую на текущую оболочку, если команда не указана.источник