C'è una differenza tra "&&" e ";" simboli in un terminale BASH standard?

52

Sembrano entrambi avvertire BASH di iniziare con un altro comando che segue i simboli ma c'è una netta differenza?

    
posta Michael Terry 27.01.2011 - 18:01

6 risposte

66

Con questa linea:

command1 && command2

comando2 verrà eseguito se (e solo se) comando1 restituisce lo stato di uscita zero, mentre in questa riga:

command1 ; command2

sia command1 che command2 saranno eseguiti indipendentemente. Il punto e virgola consente di digitare molti comandi su una riga.

    
risposta data user8290 27.01.2011 - 18:12
40

Puoi provare la differenza da solo:

  1. ls /invalid/path && echo "hello!"
    poiché / invalid / path non esiste, ls non può mostrarti l'elenco delle directory. Fallirà con un messaggio di errore: "ls: / invalid / path: nessun file o directory".
    La seconda metà del comando (echo "ciao!") È mai eseguita nemmeno perché il primo semestre è fallito.

  2. ls /invalid/path ; echo "hello!"
    Lo stesso messaggio di errore appare come prima, ma questa volta, la seconda parte viene eseguita !
    ls: / invalid / path: nessun file o directory di questo tipo
    ciao!

Perché è utile?
Supponiamo di voler estrarre un file chiamato archive.tar.gz
Potresti usare il comando tar zxvf archive.tar.gz && rm archive.tar.gz .
Se per qualsiasi ragione l'estrazione dell'archivio fallisce, la seconda parte non viene eseguita! Puoi riprovare.

Se usi; nella stessa situazione, l'archivio viene eliminato e non puoi riprovare.

    
risposta data Kenny Rasschaert 27.01.2011 - 18:37
8

&& è AND , il che significa che il secondo comando verrà eseguito solo se il primo restituito true (nessun errore).

    
risposta data Ward Muylaert 27.01.2011 - 18:11
6

Aggiornamento : ho aggiunto come script per evidenziare alcune trappole possibili:

Poiché nessun altro ha menzionato "||", io

Update2 : alcune importanti riformulazioni qui
& Amp; & amp; è come un "allora" di un'istruzione "se" che risponde a "true"

|| è NOT come il "else" di una "if" statment ..
|| è come un "then" di un'istruzione "if" che risponde a "false"

Più specificatamente, & amp; & amp; testa il $? restituisce il valore dell'istruzione precedente più recentemente eseguito e passa il controllo all'istruzione o alla sottocampo immediatamente dopo il & amp; & amp; ... passa solo il controllo se $? è vero.

|| è simile, ed è spesso visto seguendo un & amp; & amp; dichiarazione, ma verifica un valore di ritorno falso ($?) dall'istruzione precedente eseguita di recente ... NB! , Nota Bene! Nota bene! .... se l'istruzione di pre-elaborazione è un & amp; & amp; affermazione che si retrosce quando ci si aspetta che sia vero, quindi || risponderà al falso, quindi mescolare entrambi sulla stessa linea potrebbe essere rischioso

Il punto principale che sto cercando di fare è in relazione a un errore che ho fatto. vale a dire:
 ## [[condizione]] & amp; & amp; A || B
è non non si comporta come un ternario di stile C / C ++. vale a dire:
// (condizione)? A: B
Vedi lo script seguente per esempi di risultati "imprevisti" da "A"

Il test di base e il & amp; & amp; e il || la dichiarazione deve essere sulla stessa linea ...

Esegui questo script per vedere dove le cose possono andare storte quando usi & amp; & amp; e ||
L'affermazione eseguita di recente potrebbe non essere quella che ti aspetti ..

[[condizione]] & amp; & amp; echo Ciao || echo Arrivederci .... è generalmente sicuro,
perché un eco ben formato tornerà vero.
ma per quanto riguarda l'accesso a un file che non esce?

#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \
#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \%pre%  0   rc=$? ..&&.. condition is true" || echo "  \%pre%  0   rc=$? ..||.. condition is false"
 ((1!=1)) && echo  " ((1!=1)) rc=$? ..&&.. condition is true" || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && echo "  \%pre%  1   rc=$? ..&&.. condition is true" || echo "  \%pre%  1   rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \%pre%  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \%pre%  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \%pre%  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \%pre%  1   rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo  ======
 ((1==1)) || echo  " ((1==1)) rc=$? ..||.. condition is true" && echo  " ((1==1)) rc=$? ..&&.. condition is false"
  $0  0   || echo "  \%pre%  0   rc=$? ..||.. condition is true" && echo "  \%pre%  0   rc=$? ..&&.. condition is false"
 ((1!=1)) || echo  " ((1!=1)) rc=$? ..||.. condition is true" && echo  " ((1!=1)) rc=$? ..&&.. condition is false"
  $0  1   || echo "  \%pre%  1   rc=$? ..||.. condition is true" && echo "  \%pre%  1   rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \%pre%  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \%pre%  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \%pre%  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \%pre%  1   rc=$? ..||.. condition is false"

exit 
0 rc=$? ..&&.. condition is true" || echo " \%pre% 0 rc=$? ..||.. condition is false" ((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. condition is true" || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && echo " \%pre% 1 rc=$? ..&&.. condition is true" || echo " \%pre% 1 rc=$? ..||.. condition is false" echo echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' echo ====== ((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false" $0 0 && (echo " \%pre% 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \%pre% 0 rc=$? ..||.. condition is false" ((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && (echo " \%pre% 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \%pre% 1 rc=$? ..||.. condition is false" echo echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes' echo ====== ((1==1)) || echo " ((1==1)) rc=$? ..||.. condition is true" && echo " ((1==1)) rc=$? ..&&.. condition is false" $0 0 || echo " \%pre% 0 rc=$? ..||.. condition is true" && echo " \%pre% 0 rc=$? ..&&.. condition is false" ((1!=1)) || echo " ((1!=1)) rc=$? ..||.. condition is true" && echo " ((1!=1)) rc=$? ..&&.. condition is false" $0 1 || echo " \%pre% 1 rc=$? ..||.. condition is true" && echo " \%pre% 1 rc=$? ..&&.. condition is false" echo echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' echo ====== ((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false" $0 0 && (echo " \%pre% 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \%pre% 0 rc=$? ..||.. condition is false" ((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && (echo " \%pre% 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \%pre% 1 rc=$? ..||.. condition is false" exit
risposta data Peter.O 09.02.2011 - 07:42
1

try

false && echo "hello"

e

false ; echo "hello"

guarda la differenza

    
risposta data Petrie Wong 09.02.2011 - 07:19
0

Il comando (funzione, in caso di uno script) dopo && viene eseguito a seconda del RETVAL del primo comando (funzione, nel caso di uno script). Forza il primo comando a restituire il valore 0, se ha successo. Possiamo controllare il valore di ritorno per eseguire ulteriori comandi.

    
risposta data theTuxRacer 09.02.2011 - 09:07

Leggi altre domande sui tag