Qualcuno può spiegare quali sono gli usi del comando exec negli script di shell con semplici esempi?
Qualcuno può spiegare quali sono gli usi del comando exec negli script di shell con semplici esempi?
Risposte:
Il exec
comando incorporato rispecchia le funzioni nel kernel, ce ne sono una famiglia basata su execve
, che di solito viene chiamato da C.
exec
sostituisce il programma corrente nel processo corrente, senza fork
un nuovo processo. Non è qualcosa che useresti in ogni sceneggiatura che scrivi, ma a volte è utile. Ecco alcuni scenari che l'ho usato;
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-program
arresta in modo anomalo, l'utente finale non può accedere a una shell, perché non è presente: l'ha exec
sostituita.
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 csh
e tutti hanno appena inserito .login
una chiamata nel loro (file di avvio csh) ksh
. Mentre ha funzionato, ha lasciato un csh
processo vagante in esecuzione e il logout è stato in due fasi che potrebbe creare confusione. Quindi l'abbiamo cambiato in quello exec ksh
che 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 ksh
non si tratta di una shell di login).
Solo per salvare i processi. Se chiamiamo prog1 -> prog2 -> prog3 -> prog4
ecc. 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 exec
usato 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 exec
in shell come ksh
e 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 exec
ripristina 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 -u
o print -u
, su bash
, per esempio:
read <&3
echo stuff >&4
exec gunicorn
restituisce il pid corretto al supervisore.
exec
possono 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 exec
effettivamente lavorare per cambiare un descrittore di file? Perché questo particolare comando è stato scelto per questo compito? (Markdown sta fallendo in questo momento?)
exec >.\logfilename.log 2>&1
&>
è bash
un'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.
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 sh
un'istanza, quindi inizi command
come figlio di tale sh
istanza. Al command
termine, anche l' sh
istanza termina.
sh -c 'exec command'
esegue sh
un'istanza, quindi sostituisce tale sh
istanza 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' sh
istanza non è più necessaria, quindi è un'ottimizzazione (minore) semplicemente sostituire l' sh
istanza con il command
processo, 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 sh
ma volevi davvero eseguire qualcos'altro, exec something else
è ovviamente una soluzione alternativa per sostituire l' sh
istanza indesiderata (come ad esempio se volessi davvero eseguire il tuo spiffy gosh
invece di sh
ma il tuo non è elencato in/etc/shells
modo da poter non specificarlo come shell di accesso).
Il secondo uso di exec
per manipolare i descrittori di file è un argomento separato. La risposta accettata lo copre bene; per mantenerlo autonomo, rimanderò al manuale per qualsiasi cosa exec
sia seguita da un reindirizzamento invece che da un nome di comando.