Jakie są możliwe zastosowania polecenia exec?

10

Uczę się execdowodzenia. Wiem, że execpolecenie zastępuje proces, który go rozpoczął. Dlatego powrót do procesu zastąpionego execpoleceniem jest niemożliwy .

Można powiedzieć, że jego celem jest uniemożliwienie powrotu do procesu, który go rozpoczął.

Ale jakie są inne zastosowania posiadania czegoś takiego execjak polecenie?

mizech
źródło
1
z artykułu w Wikipedii: „Skrypty opakowujące często używają tego polecenia do uruchamiania programu (bezpośrednio lub za pośrednictwem interpretera lub maszyny wirtualnej) po ustawieniu zmiennych środowiskowych lub innej konfiguracji”.
kn
1
bardziej odpowiedni dla informatyki
Anwar
2
Osobiście uważam, że exec ssh server-that-does-byobu-on-login.example.combardzo mi się podoba, ponieważ ^ A ^ D całkowicie zamyka terminal. (Bardziej ogólnie exec byobu(a exec screen, exec tmux),
Williham Totland

Odpowiedzi:

9

W skrypcie opakowania

exec jest używany głównie w skryptach otoki.

Jeśli chcesz zmodyfikować środowisko dla programu przed uruchomieniem programu głównego, często piszesz skrypt, a na końcu uruchamiasz program główny. Ale w tym momencie skrypt nie musi pozostawać w pamięci. Jest więc execużywany w takich przypadkach, aby główny program mógł zastąpić skrypt macierzysty.

Oto praktyczny przykład. Jest to mate-terminal.wrapperskrypt pochodzi z mate-terminalu. Zaczyna się mate-terminalod kilku dodatkowych argumentów, sprawdzając środowiska użytkownika.

#!/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);

Należy tutaj zauważyć, że istnieje execwywołanie, które zastępuje ten skrypt w pamięci.

Oto podobne pytanie, na które odpowiedziano w witrynie StackExchange dla systemów Unix i Linux - https://unix.stackexchange.com/q/270929/19288

Aby przekierować deskryptory plików

Innym powszechnym zastosowaniem execjest przekierowywanie deskryptorów plików. stdin, stdout, stderrMoże zostać przekierowany do plików przy użyciu exec.

  1. Przekierowanie stdout- exec 1>filespowoduje, że standardowym wyjściem będzie plik nazwany filena koniec bieżącej sesji powłoki. Wszystko, co zostanie wyświetlone na wyświetlaczu, będzie znajdować się w pliku.

  2. Przekierowanie stdin- może być również użyte do przekierowania stdindo pliku. Na przykład, jeśli chcesz uruchomić plik skryptu script.sh, możesz po prostu przekierować go stdindo pliku za pomocą exec 0<script.sh.

Anwar
źródło
W porządku. Potem „mate-terminal” będzie miał PID, który ma skrypt opakowania? I czy wykorzysta pamięć, której używał skrypt otoki? Więc skrypt opakowania zniknął. W przeciwnym razie dwa skrypty istniałyby jako osobne procesy w systemie (z dwoma różnymi PID)?
mizech
@mizech tak. używają tego samego PID
Anwar
@mizech Cieszę się, że to pomogło :)
Anwar
1
Doskonały przykład, który sprawia, że ​​jest to naprawdę jasne
Zanna
Ta odpowiedź jest częściowa i nie uwzględnia jednego z ważnych (i typowych) zastosowań exec, jakim jest użycie w przekierowaniu deskryptorów plików.
heemayl
9

exec Komenda zastępuje aktualny proces powłoki z określonym poleceniem. Zwykle po uruchomieniu polecenia spawnowany jest nowy proces (rozwidlony). exec Polecenie nie tarło nowy proces. Zamiast tego bieżący proces jest nakładany na nowe polecenie. Innymi słowy, execpolecenie jest wykonywane zamiast bieżącej powłoki bez tworzenia nowego procesu.

Istnieją trzy najczęstsze zastosowania polecenia exec:

1. Zastąpienie procesu

Przykład 1: Jeśli otworzysz nowąbashpowłokę jako

$ bash 

w pstreeto wygląda

├─gnome-terminal
        ├─bash───bash───pstree

Poprzednia bashskorupa wciąż tam jest, a ty masz nową bash. Natomiast jeśli otworzysz nową powłokę bash jako,

$ exec bash

na pstreepokazy

├─gnome-terminal
        ───bash───pstree

Tutaj stary bashzostaje zastąpiony nowym. Szczególnie przydatne jest wyjście z wielokrotnego logowania w jednym poleceniu. Jest bardziej bezpieczny i eliminuje szansę na przypadkowe opuszczenie otwartego terminalu. Zobacz Wyjdź z roota i użytkownika za pomocą jednego polecenia

Przykład 2: możesz otworzyć plik jako

$ exec vi filename.txt

Po wyjściu vinie trzeba oddzielnie zamykać terminalu, ponieważ powłoka jest już wymieniona. Po zamknięciu vi terminal jest również zamknięty.

2. Metoda przekierowania deskryptorów plików w skryptach powłoki

exec Polecenia mogą być również wykorzystywane w skryptach powłoki dynamicznie otwieranie, zamykanie i kopiowanie deskryptorów plików. Pozwala to na przekierowanie STDIN, STDERR, STDOUT i innych deskryptorów plików do różnych plików w skrypcie powłoki, zamiast ciągu wywołania polecenia. Jeśli nie określisz polecenia ani argumentów, możesz określić symbole przekierowania i deskryptory plików w celu wykonania tych funkcji.

Załóżmy, że masz skrypt powłoki, w script.shktórym chcesz mieć plik dziennika script.log, którego możesz użyć execjako

LOG=/path/to/script.log
exec 1>>$LOG
exec 2>&1

co jest równoważne z

./script &>> /path/to/script.log
./script >>  /path/to/script.log 2>&1

3. Tworzenie etapów procesu za pomocą komendy exec

Możesz także użyć polecenia exec, aby utworzyć zestaw skryptów powłoki, które wykonują się jeden po drugim, podobnie jak etapy procesu. Zamiast odradzania nowych procesów za każdym razem, gdy trzeba przenieść kontrolę do następnego skryptu, należy wykonać polecenie exec.

W takim przypadku ostatnią instrukcją każdego etapu powinno być execpolecenie wywołujące następny etap.

Aby dowiedzieć się więcej, zobacz zastosowania execpolecenia w skryptach powłoki .

Uwaga: Część powyższego wzięto z tego.

souravc
źródło
1
Tylko pełna odpowiedź (jak dotąd).
heemayl
Przez cały czas, gdy używałem exec, działałem na rzecz wydajności. Jeśli uruchamiasz demona za pomocą exec, potrzebujesz tylko jednego aktywnego procesu zamiast dwóch. Pozostawienie procesu bash marnuje między innymi kilka MB pamięci RAM.
gmatht
2

O ile wiem, jest również używany do przekierowywania deskryptorów plików (na przykład STDOUT, STDERR, STDIN) skryptu bash.

Na przykład można czytać z pliku zamiast z klawiatury za pomocą przekierowania STDIN i zapisywać do pliku zamiast terminala za pomocą przekierowania STDOUT (lub może to być STDERR w zależności od programu).

Levin Palm
źródło
1
Ta odpowiedź jest częściowa i tylko uzupełnia tę odpowiedź .
heemayl