Domanda Quale è meglio: usare; o && per eseguire più comandi in una riga?


In tutorial e how-to vedo spesso i comandi combinati. Per esempio,

sudo apt-get update && sudo apt-get install pyrenamer

Sembrano esserci quattro possibili connettori: &, &&, || e ;. Sebbene il &  connettore è chiaro per me (invia un processo in background e lascia il terminale disponibile), non è chiaro quale sia la differenza tra && e ;. E non lo sapevo || fino al commento di Kaya.

Le seguenti domande riguardano la differenza tra i due connettori, ma lo fanno principalmente nei commenti:

Quindi ecco una serie di domande correlate:

  1. Qual è la differenza tra ; e &&?
  2. Quando dovresti usarli rispettivamente? Sarebbe bello vedere alcuni casi d'uso: se voglio eseguire un comando e poi dopo aver spento il mio computer, quale connettore dovrei scegliere?
  3. Quali sono i loro vantaggi e pericoli? Robie Basak menzioni in un commento a questa risposta che un comando come cd /somewhere_else; rm -Rf * può avere conseguenze distruttive se il primo elemento nella catena di comando non riesce, per esempio.
  4. Se rilevante, da dove vengono?

331
2017-08-20 16:41


origine


C'è un altro connettore che potresti non aver trovato: ||equivale a && tranne che esegue solo il secondo comando se il primo esce con uno stato diverso da zero (non riuscito). - Kaya
Nota anche che esegui il tuo script con set -e interromperà lo script in caso di fallimento come se tutti i comandi fossero connessi &&. - choroba
stackoverflow.com/questions/3573742/... - Ciro Santilli 新疆改造中心 六四事件 法轮功
Nessuno ha risposto a Qn 4 ... sospetto il comportamento di && e || è stato ispirato dal linguaggio di programmazione C. Nel caso di (x && y), se x è valutato come falso, l'intera espressione deve essere falsa, quindi un compilatore potrebbe ottimizzare la valutazione di y, nel caso fosse costosa. I moderni standard C e C ++ in realtà richiedere questa ottimizzazione, quindi i programmi possono tranquillamente assumere che y non sarà valutato se x è falso. Ad esempio, (ptr && ptr-> days> 31) non si arresterà in modo anomalo anche se ptr è nullo. Anche in C, le affermazioni finiscono con; indipendentemente dal fatto che ci sia un'altra affermazione sulla stessa linea o meno. - Kevin


risposte:


Cheatsheet:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.

606
2017-10-20 11:02



E naturalmente, A & B &: Esegui A in background, quindi esegui B in background (indipendentemente dal successo) e restituisci il controllo alla shell. Questo spesso funziona allo stesso modo di eseguire entrambi i processi contemporaneamente. - Limited Atonement
è possibile dire: eseguire uno in background, seguito da b in background solo se funzionava? ( Suppongo &&& ?) - user230910
@ user230910: sarebbe (A && B) &. - leftaroundabout
Puoi fare riferimento a documenti autorevoli per questo? - Jaime Hablutzel
@Jack Quando viene eseguito da Cronjob, non segue abbastanza questa regola, nessuna idea del perché? Per un file python - CodeGuru


&& esegue solo il secondo comando se il primo è uscito con stato 0 (ha avuto successo). ; esegue entrambi i comandi, anche se il primo esce con uno stato diverso da zero.

Il tuo esempio con && può essere ugualmente parafrasato come

if sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi

77
2017-08-20 16:46



Grazie. Ho aggiornato la domanda per assicurarmi che le diverse sottoquestioni siano facilmente distinguibili. - don.joey
@Privato: dovresti usare ; se il secondo comando non ha bisogno del precedente per avere successo. - choroba


utilizzando ; eseguirà i comandi indipendentemente dal fatto che il primo comando abbia esito positivo o meno.

utilizzando && eseguire il 2 ° comando solo quando il primo comando è stato eseguito correttamente (stato 0).

Entrambi sono usati in diverse prospettive. Come per un processo più lungo, ad esempio per un'installazione è necessario compilarlo e installarlo. dovresti make && make install. Quindi l'installazione verrà eseguita solo se make riuscito.

Quindi per i comandi dipendenti dovresti usare &&

Wring bash o comandi con comandi indipendenti ; 

Quindi, se vuoi spegnere il computer, anche il primo lavoro non funziona ; , ma se si desidera il successo completo del primo lavoro, avviare l'uso di spegnimento &&


28
2017-08-20 16:50



Grazie. Mi piace l'ultimo caso d'uso che presenti. Ho aggiornato la domanda. - don.joey


a ; b eseguirà b indipendentemente dallo stato di uscita di a. a && b eseguirà b solo se riuscito.

Questo è necessario e sufficiente per rispondere alle prime 3 domande. In particolare, il 2 è troppo ampio e non può avere una risposta definitiva "una": la soluzione migliore è decidere caso per caso.

Per quanto riguarda la quarta domanda: Sono sintassi di Bash.

Non c'è alcun pericolo intrinseco nell'usare entrambi. Ancora una volta, la definizione di cui sopra è sufficiente. Implica che tu scriverà && quando b ha effetti indesiderati se a non ha successo Non c'è bisogno di ulteriori regole o spiegazioni, IMHO.


13
2017-08-20 21:05