Qual è lo scopo di "&&" in un comando shell?


Risposte:


399

&&ti permette di fare qualcosa in base al completamento del comando precedente, ecco perché tendi a vederlo incatenato come do_something && do_something_else_that_depended_on_something.


391

Inoltre, hai anche ||quale è il logico o, e anche ;quale è solo un separatore a cui non importa cosa è successo al comando prima.

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Alcuni dettagli su questo possono essere trovati qui Elenchi di comandi nel Manuale di Bash.


5
Forse vorresti aggiungere false && echo "Will not be printed".
MTSan

112

riga di comando - qual è lo scopo di &&?

In guscio, quando vedi

$ command one && command two

l'intento è quello di eseguire il comando che segue il &&solo se il primo comando ha esito positivo. Questo è idiomatico delle conchiglie Posix e non si trova solo in Bash.

Intende impedire l'esecuzione del secondo processo se il primo fallisce.

Potresti notare che ho usato la parola "intento" - questo è per una buona ragione. Non tutti i programmi hanno lo stesso comportamento, quindi per farlo funzionare, è necessario capire cosa considera un "errore" e come lo gestisce leggendo la documentazione e, se necessario, il codice sorgente.

La tua shell considera un valore di ritorno di 0 per vero, altri numeri positivi per falso

I programmi restituiscono un segnale all'uscita. Dovrebbero restituire 0 se escono correttamente o maggiori di zero in caso contrario. Ciò consente una quantità limitata di comunicazione tra i processi.

Si &&fa riferimento a come AND_IFnella grammatica della shell posix , che fa parte di un and_orelenco di comandi, che include anche il ||quale è un OR_IFcon una semantica simile.

Simboli grammaticali, citati dalla documentazione:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

E la grammatica (citata anche dalla documentazione), che mostra che qualsiasi numero di AND_IFs ( &&) e / o OR_IFs ( ||) può essere messo insieme (come and_ordefinito in modo ricorsivo):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Entrambi gli operatori hanno la stessa precedenza e sono valutati da sinistra a destra (sono associativi di sinistra). Come dicono i documenti:

Un AND-ORelenco è una sequenza di una o più condotte separate dagli operatori "&&"e "||".

Una lista è una sequenza di uno o più E-OR elenchi separati dagli operatori ';'e '&'facoltativamente interrotto da ';', '&'o.

Gli operatori "&&"e "||"devono avere la stessa precedenza e devono essere valutati con associatività di sinistra. Ad esempio, entrambi i seguenti comandi scrivono solo la barra nell'output standard:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. Nel primo caso, il falso è un comando che esce con lo stato di 1

    $ false
    $ echo $?
    1

    il che significa echo fooche non funziona (ad es. cortocircuito echo foo). Quindi echo barviene eseguito il comando .

  2. Nel secondo caso, true esce con un codice di 0

    $ true
    $ echo $?
    0

    e quindi echo foonon viene eseguito, quindi echo barviene eseguito.


31

Un uso abbastanza comune per '&&' è la compilazione di software con autotools. Per esempio:

./configure --prefix=/usr && make && sudo make install

Fondamentalmente se la configurazione ha esito positivo, make viene eseguito per la compilazione e, se ciò ha esito positivo, make viene eseguito come root per installare il programma. Lo uso quando sono per lo più sicuro che le cose funzioneranno e mi permette di fare altre cose importanti come guardare stackoverflow e non "monitorare" i progressi.

A volte vengo davvero portato via ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Lo faccio quando per esempio realizzo un linux da zero.


2
Buono in REPL, ma per gli script preferirei set -o errexitper Bash.
Franklin Yu,

19

&&i comandi delle stringhe insieme. I comandi successivi vengono eseguiti solo se quelli precedenti hanno esito positivo.

Allo stesso modo, ||consentirà l'esecuzione del comando successivo se il precedente fallisce.

Vedi la programmazione di Bash Shell .


8

Vedi l'esempio:

mkdir test && echo "Something" > test/file

Shell proverà a creare una directory teste poi, solo se avrà successo , proverà a creare il file al suo interno.

Quindi puoi interrompere una sequenza di passaggi se uno di loro fallisce.


8

Esegue una seconda istruzione se la prima istruzione termina correttamente. Come un'istruzione if:

 if (1 == 1 && 2 == 2)
  echo "test;"

Per prima cosa prova se 1 == 1, se ciò è vero controlla se 2 == 2


1
Qualcuno potrebbe spiegare perché questo è stato sottoposto a downgrade per gli utenti che si sono imbattuti nella domanda?
user3243242

1
@ user3243242 non è sbagliato, solo un cattivo esempio per illustrare l'uso di&&
dan

È una grande idea di come iffunzionano i test in bash. Non l'ho mai pensato come una catena di comandi di confronto, che si interrompeva quando qualcuno di loro falliva. Quindi hai il mio voto :)
PiRK

1
La conseguenza è che puoi ottenere il comportamento opposto usando ||, per concatenare i comandi fino a quando uno di loro non riesce: eei || leu || uie || echo prout3 || echo "never executed"
PiRK

7

command_1 && command_2: esegue command_2 solo quando command_1 viene eseguito correttamente.

command_1 || command_2: esegue command_2 solo quando command_1 non viene eseguito correttamente.

È simile al modo in cui una condizione 'if' viene eseguita in un linguaggio di programmazione tradizionale, come, in if (condition_1 && condition_2){...}condition_2 verrà omessa se condition_1 è falsee in if (condition_1 || condition_2){...}condition_2 verrà omessa se condition_1 lo è true. Vedi, è lo stesso trucco che usi per scrivere codice :)


Non so che cosa intendi con "esattamente il contrario", ma $ echo "1" || echo '2' stampa solo '1'. e $ wrong_command || echo '2' stampa un messaggio di errore e '2' sulla riga successiva. Potresti spiegare qualcosa in più su cosa pensi sia sbagliato?
Xiaonin Li,

amico, ero sicuramente troppo stanco ieri. scusatemi, ero solo io: / Ho bisogno che modifichi qualcosa nella tua risposta se vuoi che io abbia votato (per rendere la tua risposta 0, in questo momento StackOverflow chiedi modifica in modo che io non possa)
Arount

@Arount, va bene non ti preoccupare. Quindi ho appena inviato una modifica. quindi sei in grado di rimuovere il voto negativo adesso?
Xiaonin Li,

sì, ancora una volta, scusa, davvero
Arount

0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

Quando il programma verifica se comando, il programma crea un numero chiamato codice di uscita, se entrambe le condizioni sono vere, il codice di uscita è zero (0), altrimenti il ​​codice di uscita è un numero positivo. solo quando viene visualizzato Equal se viene prodotto zero (0), significa che entrambe le condizioni sono vere.


Benvenuto in StackOverflow. Assicurati che lo snippet di codice funzioni prima di pubblicare qui. Devi correggerloif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu

1
Grazie @ZhengQu per il tuo comando, è stato fatto.
Amin
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.