Eles parecem sinalizar para o BASH começar com outro comando após os símbolos, mas há uma diferença distinta?
Eles parecem sinalizar para o BASH começar com outro comando após os símbolos, mas há uma diferença distinta?
Respostas:
Com esta linha:
command1 && command2
command2 será executado se (e somente se) command1 retornar o status de saída zero, enquanto nesta linha:
command1 ; command2
comando1 e comando2 serão executados independentemente. O ponto e vírgula permite que você digite muitos comandos em uma linha.
Você pode tentar a diferença por si mesmo:
ls /invalid/path && echo "hello!"
como / invalid / path não existe, não é possível mostrar a listagem do diretório. Ele falhará com uma mensagem de erro: "ls: / invalid / path: Esse arquivo ou diretório não existe".
A segunda metade do comando (eco "olá!") Nunca é executada porque a primeira metade falhou.
ls /invalid/path ; echo "hello!"
A mesma mensagem de erro aparece como antes, mas desta vez, a segunda parte é executada !
ls: / invalid / path: Não existe esse arquivo ou diretório
Olá!
Por que isso é útil?
Suponha que você deseja extrair um arquivo chamado archive.tar.gz
Você pode 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 novamente.
Se você usar ; na mesma situação, o arquivo é excluído e você não pode tentar novamente.
&&
é AND
, o que significa que o segundo comando será executado apenas se o primeiro retornar verdadeiro (sem erros).
AND
execução, o segundo parâmetro se torne irrelevante se o primeiro for igual false
e, portanto, o código subjacente seja otimizado para adiar a avaliação do segundo parâmetro até que ele saiba qual é o primeiro.
&&
é apenas um operador binário, uma função. A única coisa "especial" é que é a notação de infixo (que é padrão para a maioria desses tipos de operadores) e a execução atrasada do segundo operando. Essa execução atrasada realmente oferece a capacidade de ser usada como algo que pode ser conceitualmente visto como uma if
declaração nesse contexto , mas isso não tira o fato de que o uso originalmente pretendido está dentro do condicional de uma if
declaração real . O uso aqui realmente é mais um "hack".
a && b || c = (a && b) || c
. Ordem simples de avaliação. Não há realmente nenhum mistério lá. Se você os escrever como suas funções típicas, seria simplesmente parecido or(and(a, b), c)
. Essa lógica é a mesma tanto dentro de uma if
condicional quanto na entrada direta na linha de comando, porque &&
e ||
como operadores , eles pegam dois operandos e retornam outro.
Atualização : eu adicionei como script para destacar algumas das possíveis armadilhas:
Como ninguém mais mencionou "||", eu irei
Atualização2 : algumas reformulações importantes aqui
&& são como um "então" de uma declaração "se" que responde a "verdadeiro"
|| NÃO é como o "else" de uma declaração "if" ..
|| é como um "então" de uma declaração "se" que responde a "falso"
Mais especificamente, && testa o $? retorna o valor da instrução executada mais recentemente anterior e passa o controle para a instrução ou sub-shell imediatamente após o && ... ele somente passa o controle se $? é verdade.
|| é semelhante e geralmente é visto após uma instrução &&, mas testa um valor de retorno falso ($?) da instrução executada mais recentemente anterior ... NB! Nota Bene! Observe bem! .... se a instrução precedente for uma instrução && que retrocede falso quando você espera que seja verdadeira, então || responderá ao falso, portanto, misturar os dois na mesma linha pode ser arriscado
O ponto principal que estou tentando cometer é em relação a um erro que cometi. ou seja:
## [[condição]] && A || B
is not não se comporta como um ternário de estilo C / C ++. ou seja:
// (condição)? A: B
Veja o script abaixo para exemplos de resultados "inesperados" de "A"
O teste básico e os && e os || A instrução deve estar na mesma linha ...
Execute este script para ver onde as coisas podem dar errado ao usar && e ||
A instrução executada mais recentemente pode não ser a que você espera.
[[condição]] && eco Olá || eco Adeus .... normalmente é seguro,
pois um eco bem formado retornará verdadeiro.
mas e quanto a 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 " \$0 0 rc=$? ..&&.. condition is true" || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. condition is true" || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && echo " \$0 1 rc=$? ..&&.. condition is true" || echo " \$0 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 " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 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 " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 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 " \$0 0 rc=$? ..||.. condition is true" && echo " \$0 0 rc=$? ..&&.. condition is false"
((1!=1)) || echo " ((1!=1)) rc=$? ..||.. condition is true" && echo " ((1!=1)) rc=$? ..&&.. condition is false"
$0 1 || echo " \$0 1 rc=$? ..||.. condition is true" && echo " \$0 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 " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 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 " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
exit
experimentar
false && echo "olá"
e
falso; eco "olá"
Veja a diferença
O comando (função, no caso de um script) depois &&
é executado, dependendo do RETVAL do primeiro comando (função, no caso de um script). Força o primeiro comando a retornar um valor 0, se for bem-sucedido. Podemos verificar o valor de retorno para executar mais comandos.