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

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

Il comando incorporato exec mirror delle funzioni nel kernel, ce ne sono una famiglia basata su execve , che viene solitamente chiamata da C.

exec sostituisce il programma corrente nel processo corrente, senza introdurre un nuovo processo. Non è qualcosa che useresti in ogni sceneggiatura che scrivi, ma a volte è utile. Ecco alcuni scenari che 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 (say) .profile , l’ultima affermazione dice qualcosa del tipo:

      exec appln-program 

    quindi ora non c’è nessuna shell in cui tornare. Anche se il appln-program arresta in modo appln-program , l’utente finale non può accedere a una shell, perché non è presente – l’ exec sostituito.

  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 loro shell di accesso. Un sito che conosco ha avuto tutti inizio con csh , e tutti hanno appena inserito nel loro .login (csh start-up file) una chiamata a ksh . Mentre questo ha funzionato, ha lasciato un processo di csh randagio in esecuzione, e il logout era a due stadi che potrebbe creare confusione. Quindi lo abbiamo cambiato in 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 è una shell di login).

  3. Solo per salvare i processi. Se chiamiamo prog1 -> prog2 -> prog3 -> prog4 ecc. E non torniamo mai indietro, allora chiamiamo exec. Salva risorse (non molto, certamente, a meno che non vengano ripetute) e rende più semplice l’arresto.

Ovviamente hai visto exec usato da qualche parte, forse se hai mostrato il codice che ti infastidisce potremmo giustificare il suo uso.

Modifica : mi sono reso conto che la mia risposta sopra è incompleta. Ci sono due usi di exec in shell come ksh e bash – usati per aprire i 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, quindi exec ritorna al significato originale:

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

Ci sono molti modi in cui puoi usarli, in ksh usa read -u o print -u , su bash , per esempio:

 read <&3 echo stuff >&4 

Solo per aumentare la risposta accettata con una breve risposta amichevole a breve, probabilmente non hai bisogno di exec .

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

 sh -c 'command' 

si esegue un’istanza sh , quindi si avvia il command come figlio dell’istanza sh . Al termine del command , termina anche l’istanza sh .

 sh -c 'exec command' 

esegue un’istanza sh , quindi sostituisce l’ istanza sh con il command binary e lo esegue invece.

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

 command 

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

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

Questo fa un po ‘di cose per preparare l’ambiente in modo che contenga ciò che è necessario. Una volta fatto, l’istanza sh non è più necessaria, quindi è un’ottimizzazione (minore) sostituire semplicemente l’istanza sh con la procedura di command , invece di eseguirla come un processo figlio e attendere, quindi uscire al più presto come 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 quel comando come ottimizzazione.

Se qualcosa ti obbliga a correre ma vuoi davvero eseguire qualcos’altro, exec something else è ovviamente una soluzione alternativa per sostituire l’istanza sh indesiderata (come ad esempio se vuoi davvero eseguire il tuo spooky gosh invece di sh ma il tuo isn ‘elencato in /etc/shells quindi non è ansible specificarlo come shell di login).

Il secondo uso di exec per manipolare i descrittori di file è un argomento separato. La risposta accettata lo copre bene; per mantenere questo autocontenuto, mi limiterò a rimandare al manuale per qualsiasi cosa in cui exec è seguito da un reindirizzamento anziché da un nome di comando.