Quali sono gli usi del comando exec negli script di shell?


250

Qualcuno può spiegare quali sono gli usi del comando exec negli script di shell con semplici esempi?


31
I collegamenti a linux.about.com non sono utili. Non chiariscono in remoto in che modo l'esecuzione di un comando o una pipeline di comandi usando 'exec' differisce dal solo eseguirli normalmente. Da qui la domanda del PO "a che cosa serve exec"?
Jonathan Hartley,

2
Stack Overflow è un sito per domande di programmazione e sviluppo. Questa domanda sembra essere fuori tema perché non si tratta di programmazione o sviluppo. Consulta quali argomenti posso chiedere qui nel Centro assistenza. Forse Super User o Unix & Linux Stack Exchange sarebbero un posto migliore da chiedere.
JWW

Risposte:


281

Il execcomando incorporato rispecchia le funzioni nel kernel, ce ne sono una famiglia basata su execve, che di solito viene chiamato da C.

execsostituisce il programma corrente nel processo corrente, senza forkun nuovo processo. Non è qualcosa che useresti in ogni sceneggiatura che scrivi, ma a volte è utile. Ecco alcuni scenari che l'ho usato;

  1. Vogliamo che l'utente esegua un programma applicativo specifico senza accesso alla shell. Potremmo cambiare il programma di accesso in / etc / passwd, ma forse vogliamo che le impostazioni dell'ambiente vengano utilizzate dai file di avvio. Quindi, in (diciamo) .profile, l'ultima affermazione dice qualcosa del tipo:

     exec appln-program

    quindi ora non c'è shell a cui tornare. Anche se si appln-programarresta in modo anomalo, l'utente finale non può accedere a una shell, perché non è presente: l'ha execsostituita.

  2. Vogliamo usare una shell diversa da quella in / etc / passwd. Per quanto possa sembrare stupido, alcuni siti non consentono agli utenti di modificare la shell di accesso. Un sito che conosco aveva tutti con cui iniziare cshe tutti hanno appena inserito .loginuna chiamata nel loro (file di avvio csh) ksh. Mentre ha funzionato, ha lasciato un cshprocesso vagante in esecuzione e il logout è stato in due fasi che potrebbe creare confusione. Quindi l'abbiamo cambiato in quello exec kshche ha appena sostituito il programma c-shell con la shell korn e reso tutto più semplice (ci sono altri problemi con questo, come il fatto che kshnon si tratta di una shell di login).

  3. Solo per salvare i processi. Se chiamiamo prog1 -> prog2 -> prog3 -> prog4ecc. E non torniamo mai indietro, quindi ogni chiamata è un dirigente. Risparmia risorse (non molto, a dire il vero, a meno che non venga ripetuto) e semplifica l'arresto.

Ovviamente hai visto execusato da qualche parte, forse se mostrassi il codice che ti infastidisce, potremmo giustificarne l'uso.

Modifica : mi sono reso conto che la mia risposta sopra è incompleta. Ci sono due usi di execin shell come kshe bash- usato per aprire descrittori di file. Ecco alcuni esempi:

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

Si noti che la spaziatura è molto importante qui. Se si posiziona uno spazio tra il numero fd e il simbolo di reindirizzamento, si execripristina il significato originale:

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

Ci sono diversi modi è possibile utilizzare questi, sull'uso ksh read -uo print -u, su bash, per esempio:

read <&3
echo stuff >&4

22
c'è anche un altro uso che ho trovato molto utile e che vale la pena menzionare qui perché si riferisce alle applicazioni Web Python e sembra qualcosa tra le tue (fantastiche) risposte 2 e 3. Di solito eseguo applicazioni web wsgi (diciamo django o pallone) attraverso un supervisore che chiama un gunicorn app: quest'ultima notoriamente richiede parecchie variabili d'ambiente, è molto più semplice e più gestibile eseguendo gunicorn da uno script di shell che imposta tutto e infine exec gunicornrestituisce il pid corretto al supervisore.
gru,

1
I documenti affermano che execpossono essere utilizzati per il reindirizzamento:> Se il comando non è specificato, eventuali reindirizzamenti hanno effetto nella shell corrente e lo stato di ritorno è 0. Se si verifica un errore di reindirizzamento, lo stato di ritorno è 1. Ma come funziona execeffettivamente lavorare per cambiare un descrittore di file? Perché questo particolare comando è stato scelto per questo compito? (Markdown sta fallendo in questo momento?)
Ray

@Ray: meglio che posso farlo: pubs.opengroup.org/onlinepubs/009604599/utilities/exec.html . Se hai bisogno di sapere come, allora guarda il codice sorgente della shell.
cdarke,

7
Un altro uso: reindirizzare tutto l'output di uno script su un file di registroexec >.\logfilename.log 2>&1
Hogan,

1
@Carmageddon: &>è bashun'estensione (vedi man bash) e il tuo esempio è equivalente a exec >/var/log/userdata.log 2>&1. In altre parole, reindirizza stdout e stderr a quel file. I comandi che seguono erediteranno quei reindirizzamenti a meno che non vengano ripristinati, ma verranno eseguiti.
cdarke,

41

Solo per aumentare la risposta accettata con una breve risposta per i principianti, probabilmente non è necessario exec.

Se sei ancora qui, la seguente discussione dovrebbe rivelare il perché. Quando corri, diciamo,

sh -c 'command'

esegui shun'istanza, quindi inizi commandcome figlio di tale shistanza. Al commandtermine, anche l' shistanza termina.

sh -c 'exec command'

esegue shun'istanza, quindi sostituisce tale shistanza concommand binario, e corre che invece.

Naturalmente, entrambi questi sono inutili in questo contesto limitato; vuoi semplicemente

command

Ci sono alcune situazioni marginali in cui desideri che la shell legga il suo file di configurazione o che in qualche modo configuri l'ambiente come preparazione per l'esecuzione command. Questa è praticamente l'unica situazione in cui exec commandè utile.

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

Questo fa alcune cose per preparare l'ambiente in modo che contenga ciò che è necessario. Una volta fatto, l' shistanza non è più necessaria, quindi è un'ottimizzazione (minore) semplicemente sostituire l' shistanza con il commandprocesso, piuttosto che averesh eseguita come processo figlio e aspettarla, quindi uscire non appena finisce.

Allo stesso modo, se vuoi liberare quante più risorse possibili per un comando pesante alla fine di uno script di shell, potresti voler exec tale comando come ottimizzazione.

Se qualcosa ti costringe a eseguire shma volevi davvero eseguire qualcos'altro, exec something elseè ovviamente una soluzione alternativa per sostituire l' shistanza indesiderata (come ad esempio se volessi davvero eseguire il tuo spiffy goshinvece di shma il tuo non è elencato in/etc/shells modo da poter non specificarlo come shell di accesso).

Il secondo uso di execper manipolare i descrittori di file è un argomento separato. La risposta accettata lo copre bene; per mantenerlo autonomo, rimanderò al manuale per qualsiasi cosa execsia seguita da un reindirizzamento invece che da un nome di comando.


2
Resistere alla tentazione di chiamare il tuo guscio spiffy bush. Naturalmente, questo vale anche per bashqualsiasi shell Unix popolare; anche se come osserva @anishsane , Bash ottimizza segretamente bash -c 'command'facendo effettivamente exec command.
Tripleee,

1
Il codice di uscita della shell è generalmente il codice di uscita dell'ultimo comando eseguito. Naturalmente, se la shell non viene eseguita, o per eseguire il comando, lo stato di uscita della shell rifletterà quello con un codice di errore adeguato.
Tripleee,

2
@JonathanLeffler Sto deliberatamente documentando un antipattern che vedo nelle domande dei neofiti. Questo è stato richiesto da questo duplicato, ma l'ho già visto prima, quindi volevo trattarlo in modo specifico.
Tripleee,

2
@JonathanLeffler Miglioramento della formulazione minore; è sufficiente, pensi? Grazie per il feedback.
Tripleee,

2
Grazie - ho aggiunto un altro breve paragrafo su questa ottimizzazione. Non mi è molto chiaro se hai altre obiezioni o se desideri semplicemente spiegare le cose da una prospettiva diversa.
Tripleee,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.