Что делает команда "exec"?

Я не понимаю команду 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 команда завершается с ошибкой, если только оболочка не является интерактивной или опция bash execfail установлен (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 что ты имеешь в виду?

Связанные: bash - What's the difference between eval and exec? - Unix & Linux Stack Exchange

Извини, я имел в виду “что”. :stuck_out_tongue: Но ответ, похоже, отрицательный.

Но на самом деле ваш скрипт использует exec особым образом, что можно объяснить гораздо проще, я напишу ответ.

@becko `exec" - это не про процессы. Он не создает процесс.

связанные: bash - reason for exec in wrapper scripts - Unix & Linux Stack Exchange

Пожалуйста, включите код в вопрос, чтобы нам не приходилось нажимать на него, чтобы прочитать, и потому что веб-сайты меняются. Также я не могу найти использование exec на веб-странице, связанной с веб-страницей.