Я изучаю exec
команду. Я знаю, что exec
команда заменяет процесс, который ее запустил. Так что вернуться к процессу, который заменяет команда, невозможно exec
.
Можно сказать, что его цель — сделать невозможным возврат к процессу, который его начал.
Но каковы другие способы использования чего-то exec
вроде команды?
решение1
Команда exec
заменяет текущий процесс оболочки указанной командой. Обычно при запуске команды создается новый процесс (разветвляется). Команда exec
не создает новый процесс. Вместо этого текущий процесс накладывается на новую команду. Другими словами, команда exec
выполняется вместо текущей оболочки без создания нового процесса.
Существует три наиболее распространённых варианта использования команды exec:
1. Замена процесса
Пример-1:
Если вы откроете новую bash
оболочку как
$ bash
в pstree
это похоже
├─gnome-терминал ├─bash───bash───pstree
Предыдущая bash
оболочка все еще там, и вы получили новую bash
оболочку. В то время как если вы откроете новую оболочку bash как,
$ exec bash
шоуpstree
├─gnome-терминал ├─bash───pstree
Здесь старый bash
заменяется новым. Это особенно полезно для выхода из множественного входа в одной команде.Это более безопасно и исключает возможность по ошибке оставить терминал открытым.ВидетьВыход из root и пользователя с помощью одной команды
Пример-2:Вы можете открыть файл как
$ exec vi filename.txt
При выходе vi
нет необходимости закрывать терминал отдельно, так как оболочка уже заменена. Как только вы закрываете vi, терминал также закрывается.
2. Метод перенаправления файловых дескрипторов в скриптах оболочки
Команда exec
также может использоваться в сценариях оболочки для динамического открытия, закрытия и копирования файловых дескрипторов. Это позволяет выполнять перенаправление STDIN, STDERR, STDOUT и других файловых дескрипторов в различные файлы внутри сценария оболочки вместо строки вызова команды. Если вы не указываете команду или аргументы, вы можете указать символы перенаправления и файловые дескрипторы для выполнения этих функций.
Допустим, у вас есть скрипт оболочки script.sh
, для которого вы хотите создать файл журнала script.log
. Вы можете использовать его exec
как,
LOG=/path/to/script.log
exec 1>>$LOG
exec 2>&1
что эквивалентно
./script &>> /path/to/script.log
./script >> /path/to/script.log 2>&1
3. Создание этапов процесса с помощью команды exec
Вы также можете использовать команду exec для создания набора скриптов оболочки, которые выполняют друг друга последовательно, как этапы процесса. Вместо того, чтобы порождать новые процессы каждый раз, когда вам нужно передать управление следующему скрипту, вы выполняете команду exec.
В этом случае последним оператором каждого этапа должна быть exec
команда, вызывающая следующий этап.
Видетьиспользование команды exec
в скриптах оболочкидля большего.
Примечание:Часть вышеизложенного взята изэтот.
решение2
В скрипте-оболочке
exec
используется в основном в скриптах-оболочках.
Если вы хотите изменить среду для программы перед выполнением основной программы, вы часто пишете сценарий и в конце запускаете основную программу. Но нет необходимости, чтобы сценарий оставался в памяти в это время. Поэтому exec
в этих случаях используется, чтобы основная программа могла заменить материнский сценарий.
Вот практический пример. Скрипт mate-terminal.wrapper
идет с mate-terminal. Он запускается mate-terminal
с некоторыми дополнительными аргументами, проверяя пользовательские среды.
#!/usr/bin/perl -w
my $login=0;
while ($opt = shift(@ARGV))
{
if ($opt eq '-display')
{
$ENV{'DISPLAY'} = shift(@ARGV);
}
elsif ($opt eq '-name')
{
$arg = shift(@ARGV);
push(@args, "--window-with-profile=$arg");
}
elsif ($opt eq '-n')
{
# Accept but ignore
print STDERR "$0: to set an icon, please use -name <profile> and set a profile icon\n"
}
elsif ($opt eq '-T' || $opt eq '-title')
{
push(@args, '-t', shift(@ARGV));
}
elsif ($opt eq '-ls')
{
$login = 1;
}
elsif ($opt eq '+ls')
{
$login = 0;
}
elsif ($opt eq '-geometry')
{
$arg = shift(@ARGV);
push(@args, "--geometry=$arg");
}
elsif ($opt eq '-fn')
{
$arg = shift(@ARGV);
push(@args, "--font=$arg");
}
elsif ($opt eq '-fg')
{
$arg = shift(@ARGV);
push(@args, "--foreground=$arg");
}
elsif ($opt eq '-bg')
{
$arg = shift(@ARGV);
push(@args, "--background=$arg");
}
elsif ($opt eq '-tn')
{
$arg = shift(@ARGV);
push(@args, "--termname=$arg");
}
elsif ($opt eq '-e')
{
$arg = shift(@ARGV);
if (@ARGV)
{
push(@args, '-x', $arg, @ARGV);
last;
}
else
{
push(@args, '-e', $arg);
}
last;
}
elsif ($opt eq '-h' || $opt eq '--help')
{
push(@args, '--help');
}
}
if ($login == 1)
{
@args = ('--login', @args);
}
exec('mate-terminal',@args);
Здесь следует отметить, что есть exec
вызов, который заменяет этот скрипт в памяти.
Вот ответ на аналогичный вопрос на сайте Unix & Linux StackExchange -https://unix.stackexchange.com/q/270929/19288
Для перенаправления файловых дескрипторов
Другое распространенное применение exec
— перенаправление файловых дескрипторов. stdin
, stdout
, stderr
можно перенаправить в файлы с помощью exec.
Перенаправление
stdout
-exec 1>file
приведет к тому, что стандартный вывод будет файлом, названнымfile
по имени конца текущего сеанса оболочки. Все, что должно быть выведено на дисплей, будет находиться в файле.Перенаправление
stdin
- его также можно использовать для перенаправленияstdin
в файл. Например, если вы хотите выполнить файл скриптаscript.sh
, вы можете просто перенаправитьstdin
в файл, используяexec 0<script.sh
.
решение3
Насколько мне известно, он также используется для перенаправления файловых дескрипторов (например, STDOUT, STDERR, STDIN) bash-скрипта.
Так, например, вы можете читать из файла вместо клавиатуры, используя перенаправление STDIN, и записывать в файл вместо терминала, используя перенаправление STDOUT (или STDERR, в зависимости от программы).