Я не понимаю команду bash exec
. Я видел, как он использовался внутри скриптов для перенаправления всех выходных данных в файл (как показано в этот). Но я не понимаю, как это работает или что он делает в целом. Я прочитал справочные страницы, но я их не понимаю.
man bash
говорит:
exec [-cl] [-a name] [command [arguments]] If command is specified, it replaces the shell. No new process is created. The arguments become the arguments to command. If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what login(1) does. The -c option causes command to be executed with an empty environment. If -a is supplied, the shell passes name as the zeroth argument to the executed command. If command cannot be executed for some reason, a non-interactive shell exits, unless the execfail shell option is enabled. In that case, it returns failure. An interactive shell returns failure if the file cannot be executed. If command is not specified, any redirections take effect in the current shell, and the return status is 0. If there is a redirection error, the return status is 1.
Последние две строки - это то, что важно: если вы запустите exec
сам по себе, без команды, он просто заставит перенаправления применяться к текущей оболочке. Вы, вероятно, знаете, что, когда вы бежите command > file
, выход из command
записывается в file
вместо того, чтобы на ваш терминал (это называется перенаправление). Если вы запустите exec > file
вместо этого перенаправление применяется ко всей оболочке: любой вывод, созданный оболочкой, записывается в file
вместо того, чтобы обращаться к вашему терминалу. Например, здесь
bash-3.2$ bashbash-3.2$ exec > filebash-3.2$ datebash-3.2$ exitbash-3.2$ cat fileThu 18 Sep 2014 23:56:25 CEST
Я впервые начинаю новую bash
ракушка. Затем в этой новой оболочке я запускаю exec > file
, так что все выходные данные перенаправляются на file
. Действительно, после этого я бегу date
но я не получаю никаких выходных данных, потому что выходные данные перенаправляются на file
. Затем я выхожу из своей оболочки (так что перенаправление больше не применяется), и я вижу, что file
действительно содержит выходные данные date
команда, которую я запустил ранее.
exec
это команда с двумя очень разными поведениями, в зависимости от того, используется ли с ней хотя бы один аргумент или вообще не используется ни один аргумент.
Если передается хотя бы один аргумент, первый из них принимается в качестве имени команды и
exec
попробуйте выполнить его как команду, передав оставшиеся аргументы, если таковые имеются, этой команде и управляя перенаправлениями, если таковые имеются.Если команда, переданная в качестве первого аргумента, не существует, текущая оболочка, а не только
exec
команда завершается с ошибкой, если только оболочка не является интерактивной или опция bashexecfail
установлен (shopt -s execfail
). См. также https://superuser.com/questions/992204/why-does-exec-non-existent-file-exits-the-shell-when-in-a-script-that-is-sourcЕсли команда существует и является исполняемой, она заменяет текущую оболочку. Это означает, что если
exec
появляется в скрипте, инструкции, следующие за вызовом exec никогда не будет казнен (если толькоexec
сам находится в подоболочке). Успешныйexec
никогда не возвращается. Ловушки оболочки, такие как "ВЫХОД", также не будут срабатывать.Если аргумент не передается,
exec
используется только для переопределения текущих файловых дескрипторов оболочки. Оболочка продолжается после того, какexec
, в отличие от предыдущего случая, но стандартный ввод, вывод, ошибка или любой другой дескриптор файла, который был перенаправлен, вступают в силу.Если некоторые из перенаправлений используют
/dev/null
, любой ввод из него вернет EOF, а любой вывод на него будет отброшен.Вы можете закрыть файловые дескрипторы с помощью
-
как источник или пункт назначения, напримерexec <&-
. Последующее чтение или запись в этом случае завершатся неудачей.
Вот два примера:
echo foo > /tmp/barexec < /tmp/bar # exec has no arguments, will only affect current shell descriptors, here stdincat # simple command that read stdin and write it to stdout
Этот скрипт выведет "foo" в качестве команды cat, вместо того, чтобы ждать ввода пользователя, как это было бы в обычном случае, будет принимать свои входные данные из файла /tmp/bar, который содержит foo.
echo foo > /tmp/barexec wc -c < /tmp/bar # exec has two arguments, the control flow will switch to the wc commandcat
Этот скрипт отобразит 4
(количество байт в /tmp/bar) и немедленно завершается. То cat
команда не будет выполнена.
Чтобы понять exec
вам нужно сначала понять fork
Я стараюсь быть кратким.
Когда вы подходите к развилке дорог, у вас обычно есть два варианта. Программы Linux достигают этой развилки на дороге, когда они попадают в
fork()
системный вызов.Обычные программы - это системные команды, которые существуют в скомпилированной форме в вашей системе. Когда такая программа выполняется, создается новый процесс. Этот дочерний процесс имеет ту же среду, что и его родительский, отличается только идентификационный номер процесса. Эта процедура называетсяраздвоение.
- Разветвление предоставляет способ для существующего процесса запустить новый. Однако могут возникнуть ситуации, когда дочерний процесс не является частью той же программы, что и родительский процесс. В этом случае
exec
используется.exec
заменит содержимое текущего запущенного процесса информацией из двоичного файла программы. - После процесса разветвления адресное пространство дочернего процесса перезаписывается новыми данными процесса. Это делается с помощью execcall к системе.
В bash
, если вы это сделаете help exec
:
$ help execexec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...] Replace the shell with the given command. Execute COMMAND, replacing this shell with the specified program. ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified, any redirections take effect in the current shell. Options: -a name pass NAME as the zeroth argument to COMMAND -c execute COMMAND with an empty environment -l place a dash in the zeroth argument to COMMAND If the command cannot be executed, a non-interactive shell exits, unless the shell option `execfail' is set. Exit Status: Returns success unless COMMAND is not found or a redirection error occurs.
Соответствующий бит:
If COMMAND is not specified, any redirections take effect in the current shell.
exec
это встроенная оболочка, который является оболочечным эквивалентом exec
семья из системные вызовы тот G_P говорит о (и чьи справочные страницы вы, по-видимому, прочитали). У него просто есть Предписанный POSIX функциональность воздействия на текущую оболочку, если не указана команда.
@fkraiem что ты имеешь в виду?
Извини, я имел в виду “что”. Но ответ, похоже, отрицательный.
Но на самом деле ваш скрипт использует exec
особым образом, что можно объяснить гораздо проще, я напишу ответ.
@becko `exec" - это не про процессы. Он не создает процесс.
Пожалуйста, включите код в вопрос, чтобы нам не приходилось нажимать на него, чтобы прочитать, и потому что веб-сайты меняются. Также я не могу найти использование exec
на веб-странице, связанной с веб-страницей.