Какое возможно использование команды exec?

10

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

Можно сказать, что его цель - сделать невозможным возврат к процессу, который его начал.

Но каковы другие способы использования чего-то вроде execкоманды?

mizech
источник
1
из статьи в википедии: «Сценарии Wrapper часто используют эту команду для запуска программы (напрямую, через интерпретатор или виртуальную машину) после установки переменных среды или другой конфигурации».
knb
1
больше подходит для информатики
Anwar
2
Лично я нахожу exec ssh server-that-does-byobu-on-login.example.comочень приятным то, что ^ A ^ D вообще закрывает терминал. (В более общем смысле, exec byobu(или exec screen, exec tmux).
Виллихем Тотланд

Ответы:

9

В скрипте

exec используется в основном в скриптах-обёртках.

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

Вот практический пример этого. Это mate-terminal.wrapperскрипт поставляется с Mate-терминал. Он начинается 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.

  1. Перенаправление stdout- exec 1>fileприведет к тому, что стандартным выводом будет файл с именем fileдля конца текущего сеанса оболочки. Все, что выводится на дисплей, будет в файле.

  2. Перенаправление stdin- это также может быть использовано для перенаправления в stdinфайл. Например, если вы хотите выполнить файл сценария script.sh, вы можете просто перенаправить stdinего в файл, используя exec 0<script.sh.

Анвар
источник
Ладно. После этого у 'mate-Terminal' будет PID, который имеет скрипт-обертка? И будет ли использоваться память, которую использовал скрипт-обертка? Так что скрипт-обертка исчез. В противном случае эти два сценария будут существовать как отдельные процессы в системе (с двумя разными PID)?
Мизех
@mizech да. они используют один и тот же PID
Anwar
@mizech Рад, что это помогло :)
Анвар
1
Отличный пример, который проясняет
ситуацию
Этот ответ является частичным и пропускает одно из важных (и типичных) применений exec: он используется при перенаправлении файловых дескрипторов.
Heemayl
9

Команда 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команды в сценариях оболочки для получения дополнительной информации.

Примечание: часть выше взята из этого.

souravc
источник
1
Единственный полный ответ (пока).
Heemayl
Все времена, когда я использовал exec, были для эффективности. Если вы запускаете демон с exec, вам нужно иметь только один активный процесс вместо двух. Помимо всего прочего, процесс bash приводит к потере нескольких МБ ОЗУ.
января
2

Насколько я знаю, он также используется для перенаправления файловых дескрипторов (например, STDOUT, STDERR, STDIN) bash-скрипта.

Так, например, вы можете читать из файла вместо клавиатуры с помощью перенаправления STDIN и записывать в файл вместо терминала с помощью перенаправления STDOUT (или может быть STDERR в зависимости от программы).

Левин Палм
источник
1
Этот ответ частичный и только дополняет этот ответ .
Heemayl