it-swarm.com.ru

Каковы применения команды exec в сценариях оболочки?

Может кто-нибудь объяснить простыми примерами использования команды exec в сценариях Shell?

230
user2400564

Встроенная команда exec выполняет зеркалирование в ядре, существует семейство из них на основе execve, которое обычно вызывается из C.

exec заменяет текущую программу в текущем процессе, без forking нового процесса. Это не то, что вы бы использовали в каждом сценарии, который вы пишете, но иногда это удобно. Вот несколько сценариев, которые я использовал;

  1. Мы хотим, чтобы пользователь запускал определенную прикладную программу без доступа к командной консоли. Мы могли бы изменить программу входа в/etc/passwd, но, возможно, мы хотим, чтобы настройки среды использовались из файлов запуска. Итак, в (скажем) .profile последнее утверждение говорит что-то вроде:

     exec appln-program
    

    так что теперь нет Shell, к которому можно вернуться. Даже если appln-program дает сбой, конечный пользователь не может попасть в оболочку, потому что ее там нет - exec заменил ее.

  2. Мы хотим использовать оболочку, отличную от той, что находится в/etc/passwd. Как ни странно, некоторые сайты не позволяют пользователям изменять свой вход в оболочку. На одном сайте, который я знаю, все начинали с csh, и все просто помещали в свой .login (файл запуска csh) вызов ksh. Хотя это сработало, он оставил запущенный процесс csh, и выход из системы был двухэтапным, что могло привести к путанице. Поэтому мы изменили его на exec ksh, который просто заменил программу c-Shell на korn Shell, и упростил все (с этим связаны и другие проблемы, такие как тот факт, что ksh не является оболочкой входа в систему).

  3. Просто чтобы сохранить процессы. Если мы вызываем prog1 -> prog2 -> prog3 -> prog4 и т.д. И никогда не возвращаемся, тогда каждый вызов будет исполнителем. Это экономит ресурсы (правда, не так много, если не повторяется) и упрощает отключение.

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

Правка: Я понял, что мой ответ выше не является полным. Существует два использования exec в оболочках, таких как ksh и bash - для открытия файловых дескрипторов. Вот некоторые примеры:

exec 3< thisfile          # open "thisfile" for reading on file descriptor 3
exec 4> thatfile          # open "thatfile" for writing on file descriptor 4
exec 8<> tother           # open "tother" for reading and writing on fd 8
exec 6>> other            # open "other" for appending on file descriptor 6
exec 5<&0                 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4                 # copy write file descriptor 4 onto 7
exec 3<&-                 # close the read file descriptor 3
exec 6>&-                 # close the write file descriptor 6

Обратите внимание, что расстояние очень важно здесь. Если вы поместите пробел между номером fd и символом перенаправления, то exec вернется к первоначальному значению:

  exec 3 < thisfile       # oops, overwrite the current program with command "3"

Существует несколько способов их использования, например, для ksh: read -u или print -u, для bash, например:

read <&3
echo stuff >&4
262
cdarke

Просто чтобы дополнить принятый ответ коротким коротким ответом для новичков, вам, вероятно, не нужно exec.

Если вы все еще здесь, следует надеяться, что последующее обсуждение покажет, почему. Когда вы бежите, скажем,

sh -c 'command'

вы запускаете экземпляр sh, а затем запускаете command как дочерний элемент этого экземпляра sh. Когда command завершается, экземпляр sh также завершается.

sh -c 'exec command'

запускает экземпляр sh, затем заменяет этот экземпляр sh двоичным файлом command и запускает его вместо этого.

Конечно, оба они бесполезны в этом ограниченном контексте; ты просто хочешь

command

Есть некоторые крайние ситуации, когда вы хотите, чтобы оболочка прочитала свой файл конфигурации или каким-то иным образом настроила среду в качестве подготовки к запуску command. Это практически единственная ситуация, когда exec command полезен.

#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command

Это делает некоторые вещи для подготовки среды, чтобы она содержала то, что нужно. Как только это будет сделано, экземпляр sh больше не требуется, и поэтому (незначительная) оптимизация заключается в простой замене экземпляра sh процессом command вместо того, чтобы sh запускал его как дочерний процесс и ждал его, а затем завершил работу, как только как это заканчивается.

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

Если что-то заставляет вас запускать sh, но вы действительно хотите запустить что-то другое, exec something else, конечно, является обходным решением для замены нежелательного экземпляра sh (как, например, если вы действительно хотите запустить свой собственный spiffy gosh вместо sh, но ваш - нет). перечислены в /etc/shells, поэтому вы не можете указать его в качестве оболочки входа в систему).

Второе использование exec для манипулирования дескрипторами файлов - это отдельная тема. Принятый ответ охватывает это хорошо; чтобы сохранить это самодостаточным, я просто обращусь к руководству для всего, где exec сопровождается перенаправлением вместо имени команды.

37
tripleee