Existe diferença entre '&&' e ';' símbolos em um terminal BASH padrão?

54

Eles parecem sinalizar BASH para começar com outro comando seguindo os símbolos, mas existe uma diferença distinta?

    
por Michael Terry 27.01.2011 / 18:01

6 respostas

71

Com esta linha:

command1 && command2

o comando2 será executado se (e somente se) o comando1 retornar o status de saída zero, enquanto nesta linha:

command1 ; command2

o comando1 e o comando2 serão executados independentemente. O ponto-e-vírgula permite que você digite muitos comandos em uma linha.

    
por user8290 27.01.2011 / 18:12
41

Você pode experimentar a diferença por si mesmo:

  1. ls /invalid/path && echo "hello!"
    como / invalid / path não existe, ls não pode mostrar a listagem do diretório. Ele falhará com uma mensagem de erro: "ls: / invalid / path: nenhum arquivo ou diretório". A segunda metade do comando (echo "hello!") Nunca foi executada porque a primeira metade falhou.

  2. ls /invalid/path ; echo "hello!"
    A mesma mensagem de erro aparece como antes, mas, desta vez, a segunda parte é executada !
    ls: / invalid / path: nenhum arquivo ou diretório ola!

Por que isso é útil?
Suponha que você queira extrair um arquivo chamado archive.tar.gz
Você poderia usar o comando tar zxvf archive.tar.gz && rm archive.tar.gz .
Se por algum motivo a extração do arquivo falhar, a segunda parte não será executada! Você pode tentar de novo.

Se você usa; na mesma situação, o arquivo é excluído e você não pode tentar novamente.

    
por Kenny Rasschaert 27.01.2011 / 18:37
8

&& é AND , o que significa que o segundo comando só será executado se o primeiro retornar verdadeiro (sem erros).

    
por Ward Muylaert 27.01.2011 / 18:11
7

Atualizar : adicionei como script para destacar algumas das possíveis armadilhas:

Porque ninguém mais mencionou "||", eu irei

Update2 : algumas reformulações importantes aqui
& & é como um "então" de uma declaração "if" que responde a "true"

|| é NÃO como o "else" de uma declaração "if" ..
|| é como um "então" de uma declaração "if" que responde a "false"

Mais especificamente, & & testa o $? valor de retorno da instrução anterior executada mais recentemente e passa o controle para a instrução ou sub-shell imediatamente após o & ... ela só passa o controle se $? é verdade.

|| é semelhante e costuma ser visto após um & & statement, mas testa para um valor de retorno false ($?) da declaração anterior executada mais recentemente ... NB! , Nota Bene! Note bem! .... se a declaração precedente for um & & declaração que retrocede falso quando você espera que seja verdade, então || irá responder ao falso, então misturar ambos na mesma linha pode ser arriscado

O ponto principal que estou tentando fazer é em relação a um erro que cometi. ie:
 ## [[condition]] & & A || B
é não não se comporta como um ternário de estilo C / C ++. ie:
// (condição)? A: B
Veja o script abaixo para exemplos de resultados "inesperados" de "A"

O teste básico e o & & e o || declaração deve estar na mesma linha ...

Execute este script para ver onde as coisas podem dar errado ao usar & & e ||
A declaração executada mais recentemente pode não ser a que você espera.

[[condição]] & & eco Olá || eco Goodbye .... é tipicamente seguro,
porque um eco bem formado retornará verdadeiro.
mas que tal acessar um arquivo que não sai?

#!/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
por Peter.O 09.02.2011 / 07:42
1

tente

false && echo "hello"

e

false ; echo "hello"

veja a diferença

    
por Petrie Wong 09.02.2011 / 07:19
0

O comando (function, no caso de um script) após && é executado dependendo do RETVAL do primeiro comando (function, no caso de um script). Força o primeiro comando a retornar um valor de 0, se bem-sucedido. Podemos verificar o valor de retorno para executar outros comandos.

    
por theTuxRacer 09.02.2011 / 09:07