Perché eseguire un comando shell Linux con '&'?


30

Sto usando Red Hat Linux Enterprise versione 5. Ho notato che a volte le persone eseguono comandi con un paio di &opzioni. Ad esempio, nel comando seguente, ci sono due &segni. Qual è lo scopo di loro? Sono sempre usati insieme a Nohup?

nohup foo.sh <script parameters> >& <log_file_name> &

Risposte:


15

Oltre alle risposte di Martin, Ash e Kevin, a volte vedrai una e commerciale usata matematicamente per un AND bit a bit * :

$ echo $(( 11 & 7 ))
3

Nel caso in cui non si abbia familiarità con gli operatori bit:

11: 1011
 7: 0111
-------- AND
 3: 0011

In ogni posizione c'è un bit nel primo numero E nel secondo numero, imposta quel bit su uno nella risposta.

* La funzione nella risposta di Kevin viene definita AND logica .

Per elaborare la risposta di Ash, quando usata nel reindirizzamento la e commerciale può dire alla shell di copiare un descrittore di file. In questo comando echo "hello" > outputfile 2>&1la e commerciale fa sì che qualsiasi output che può andare all'errore standard (stderr, descrittore di file 2) vada nella stessa posizione dell'output standard (stdout, descrittore di file 1, predefinito per il lato sinistro di >). L' >& outputfileoperatore è abbreviato per > outputfile 2>&1.

Inoltre, nuovo in Bash 4, ci sono due nuovi terminatori per le clausole nel casecomando ;&e ;;&che influenzano se un caso "fallisce" e, in tal caso, se viene eseguito il test successivo.


Bene, Dennis! Supponiamo che io utilizzi il registro terminale ssh in una macchina, quindi usi il terminale ssh per eseguire il comando (supponiamo un processo a lungo termine), quindi se chiudo la sessione del terminale, il processo a lungo termine del comando verrà terminato correttamente? E se voglio che il comando continui ad essere eseguito anche se esco dalla shell, dovrei usare nohup, o & (alla fine del comando) o usare sia nohup che &?
George2,

1
@ George2: No, >& filenamegenera sia stdout che stderr nello stesso file. Se vuoi reindirizzare solo stderr (e lasciare solo stdout), lo faresti 2> filename. Per quanto riguarda l'altra domanda, molto probabilmente useresti entrambi nohupe &.
In pausa fino a nuovo avviso.

1
@ George2: se non si esegue il background del comando, non si riceverà un prompt della shell in modo da poter emettere un comando logouto exit.
In pausa fino a nuovo avviso.

2
George: Se non usi &, non riceverai mai il tuo prompt per fare nient'altro. Il terminale verrà "bloccato" fino al termine del processo (qualunque esso sia) o venga terminato / interrotto. Il & garantisce che il processo viene eseguito in background. Tuttavia, se ci si disconnette, il sistema operativo interromperà tutti i processi, il che interrompe anche il processo in background. Se usi nohup stai dicendo al processo "ignora il comando che ti terminerà".
Martin Marconcini,

1
@ George2: Sì. "immune to hangups" == "process continue" e "non-tty" == "quit terminal console"
In pausa fino a nuovo avviso.

32

In uno script di shell Bash, la e commerciale "&" viene utilizzata per fork i processi:

find -name hello &

Farà in modo che il comando find venga biforcato ed eseguito in background (puoi sempre ucciderlo dal suo PID).


Grazie Martin, supponiamo che io utilizzi log del terminale ssh in una macchina, quindi usi il terminale di ssh per eseguire il comando (supponiamo un processo a lungo termine), quindi se chiudo la sessione del terminale, il processo a lungo termine del comando verrà terminato correttamente ? E se eseguo il comando usando & in ssh terminal, anche se esco dal terminale, il processo a lungo termine del comando è ancora in esecuzione, giusto?
George2,

1
Questo è corretto George. I processi in background dovrebbero continuare fino a quando non terminano o non li uccidi. Tuttavia, come è già stato sottolineato, non sarà necessario nohup per evitare che il processo muoia quando l'utente si disconnette.
Martin Marconcini,

Grazie Martin! Voglio sapere perché dobbiamo usare entrambi & e nohup e quali sono le loro singole funzioni che ci fanno raggiungere l'obiettivo di far continuare l'esecuzione del comando anche se la console del terminale si chiude. Ho letto la pagina man per nohup, e si dice "esegui un comando immune agli hangup, con output a non-tty", sono confuso se l'immunità agli hangup è ciò che vuoi dire lasciando che il comando continui a funzionare senza essere influenzato da quit console terminale? Se è così, penso che usare nohup sia sufficiente e non sia necessario usare &. Qualche commento?
George2,

1
Devi usare Entrambi, se non usi &, il terminale non ti permetterà di inserire altri comandi. Il modo migliore per vederlo è semplicemente provarlo. Un buon esempio è un comando che richiede un po 'di tempo, come un find: find -name SomeName /> somefile.txt provalo con nohup e & e vedi le differenze.
Martin Marconcini,

Questa è un'ottima risposta per la domanda nohup: serverfault.com/questions/311593/…
joshperry,

26

Perché eseguire un comando shell Linux con '&'?

Per recuperare immediatamente il prompt ed eseguire il processo in background.

Quali sono le loro funzioni?

nohup consente al processo in background di continuare l'esecuzione anche dopo che l'utente si è disconnesso (o è uscito dalla shell di avvio).

> & reindirizza sia l'output standard sia l'errore standard nel file di registro.

e esegue tutto in background, restituendoti immediatamente il tuo prompt.

Spiegazione:

Ogni processo Linux apre tre canali I / O, un input "stdin", un output standard "stdout" e un output errore standard "stderr". Possono essere usati per i binari, ma sono tradizionalmente testo. Quando la maggior parte dei programmi vede chiudere lo stdin, questi escono (questo può essere modificato dal programmatore).

Quando la shell genitore esce, lo stdin viene chiuso sui bambini e (spesso, di solito) anche i bambini escono. Inoltre, i bambini ricevono un segnale software, SIGHUP, che indica che l'utente ha "riagganciato" (in precedenza, il modem) e anche qui l'impostazione predefinita è uscire. (Nota, un programmatore può cambiare tutto questo quando scrive il programma).

Quindi, ciò che fa nohup è dare al processo figlio un ambiente I / O separato, legando i dettagli in qualcosa che non è legato alla shell genitore e proteggendo il bambino dal segnale SIGHUP. Una volta che l'utente si disconnette, vedrai il processo in background nohup di proprietà di init (processo 1), non la shell dell'utente.

Tuttavia, nohupnon è possibile eseguire completamente il lavoro se il processo viene eseguito in primo piano, quindi &viene utilizzato per eseguire il programma in background, dove può tranquillamente rimanere in esecuzione con o senza un utente connesso.


Supponiamo che io utilizzi il registro terminale ssh in una macchina, quindi usi il terminale ssh per eseguire il comando (supponiamo un processo a lungo termine), quindi se chiudo la sessione del terminale, il processo a lungo termine del comando verrà terminato correttamente? E se voglio che il comando continui ad essere eseguito anche se esco dalla shell, dovrei usare nohup, o & (alla fine del comando) o usare sia nohup che &?
George2,

1
Corretto, utilizzare sia nohup che & affinché il processo continui dopo la disconnessione di SSH.
kmarsh

Grazie Kmarsh! Voglio sapere perché dobbiamo usare entrambi & e nohup e quali sono le loro singole funzioni che ci fanno raggiungere l'obiettivo di far continuare l'esecuzione del comando anche se la console del terminale si chiude. Ho letto la pagina man per nohup, e si dice "esegui un comando immune agli hangup, con output a non-tty", sono confuso se l'immunità agli hangup è ciò che vuoi dire lasciando che il comando continui a funzionare senza essere influenzato da quit console terminale? Se è così, penso che usare nohup sia sufficiente e non sia necessario usare &. Qualche commento?
George2,

1
Modificherò la mia risposta per rispondere.
kmarsh

13

Oltre alla risposta di @ Martin: l'altro uso della e commerciale ( >&come sopra) è quello di catturare sia stdoute stderr. Normalmente, se si reindirizza l'output su un file con solo '>', si otterrebbe solo l'output su stdout, senza errori.


1. Grazie Ash, voglio confermare con te che "> & <nome file registro>" scaricherà tutti gli standard stderr e stdout nel file di registro, giusto? 2. E usando "> <nome file registro>" verrà scaricato tutto lo stdout nel file registro, giusto?
George2,

1
@Gorge: Sì, esatto.
Ash,

Grazie Ash! Voglio sapere perché dobbiamo usare entrambi & e nohup e quali sono le loro singole funzioni che ci fanno raggiungere l'obiettivo di far continuare l'esecuzione del comando anche se la console del terminale si chiude. Ho letto la pagina man per nohup, e si dice "esegui un comando immune agli hangup, con output a non-tty", sono confuso se l'immunità agli hangup è ciò che vuoi dire lasciando che il comando continui a funzionare senza essere influenzato da quit console terminale? Se è così, penso che usare nohup sia sufficiente e non sia necessario usare &. Qualche commento?
George2,

4

Oltre alla risposta di Martin e Ash, a volte potresti vedere l'uso di un &&token. Questo è usato per dire "esegui il secondo comando se e solo se il primo comando è stato eseguito correttamente." Un comando ben scritto, se presenta errori, non verrà chiuso correttamente.

[kevin@box ~]$ ls file && echo removing file && rm file
ls: file: No such file or directory
[kevin@box ~]$ touch file
[kevin@box ~]$ ls file && echo removing file && rm file
file
removing file
[kevin@box ~]$

Bene, Kevin! Supponiamo che io utilizzi il registro terminale ssh in una macchina, quindi usi il terminale ssh per eseguire il comando (supponiamo un processo a lungo termine), quindi se chiudo la sessione del terminale, il processo a lungo termine del comando verrà terminato correttamente? E se voglio che il comando continui a essere eseguito anche se esco dalla shell, dovrei usare nohup, o & (alla fine del comando) o usare sia nohup che &?
George2,

O uno funzionerebbe. NOHUP era il modo originale di farlo, immagino (ma sto indovinando totalmente), ma lo sfondo funziona ora. Una differenza importante è quando si esegue una shell interattiva immergendosi in un sistema remoto. Il processo NOHUP verrebbe eseguito in primo piano, ma continuerebbe a funzionare se si esce, mentre il processo in background ritornerebbe immediatamente dopo aver generato il comando. Ma quando si tenta di uscire da una shell interattiva con un comando in esecuzione in background, si viene avvisati per primi.
Kevin M,

2

La risposta di Martin è buona, ma un po 'ambigua. Il comando è sempre fork 'ed eseguito', ma il normale comportamento della shell è di attendere il comando fino alla sua uscita. La e commerciale lo mette in background in modo da riavere il prompt del terminale e fare altre cose. Se il processo sputa i dati su stdout o stderr, questo verrà mescolato con qualsiasi cosa tu stia facendo al prompt e potrebbe confonderti. Questo è il motivo per cui reindirizzi quindi con> & /path/to/logfile.txt.

In risposta a George2, il comportamento normale per l'uscita di una shell è di inviare il segnale SIGHUP a tutti i processi nello stesso gruppo di processi (essenzialmente roba che hai generato) e di solito terminano. Se vuoi che questo continui anche se chiudi il processo di shell, puoi usare il comando nohup per far loro ignorare questo segnale e continuare a correre. C'è un nome speciale per questo tipo di processo, si chiama processo demone (pronunciato 'demone').


Grazie Rich! Supponiamo che io utilizzi il registro terminale ssh in una macchina, quindi usi il terminale ssh per eseguire il comando (supponiamo un processo a lungo termine), quindi se chiudo la sessione del terminale, il processo a lungo termine del comando verrà terminato correttamente? E se voglio che il comando continui a essere eseguito anche se esco dalla shell, dovrei usare nohup, o & (alla fine del comando) o usare sia nohup che &? E perché?
George2,

Ehi, George, mi dispiace, sto rispondendo così tardi. Sì, se si esce dalla shell, il processo a lungo termine verrà interrotto. Se vuoi che continui, devi fare sia nohup (per non terminarlo quando la shell si chiude) sia & (per mettere in background, così puoi Crtl-D o uscire dalla shell). Puoi anche guardare il comando setsid, che permetterà al tuo processo di essere eseguito, facendolo ignorare SIGHUP in un modo leggermente diverso.
Rich Homolka,

Ottima risposta, spiega le migliori pratiche per i processi avviati dalla shell in background.
Marcel Valdez Orozco,
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.