Uso confuso de && e || operadores

63

Eu estava vasculhando um arquivo /etc/rc.d/init.d/sendmail (sei que quase nunca é usado, mas estou estudando para um exame) e fiquei um pouco confuso sobre os operadores && e || . Eu li onde eles podem ser usados em declarações como:

if [ test1 ] && [ test2 ]; then
     echo "both tests are true"
elif [ test1 ] || [ test2 ]; then
     echo "one test is true"
fi

No entanto, este script mostra instruções de linha única, como:

[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE"
[ -f /usr/sbin/sendmail ] || exit 0

Eles parecem estar usando os operadores && e || para obter respostas com base em testes, mas não consegui descobrir a documentação sobre esse uso específico desses operadores. Alguém pode explicar o que eles fazem nesse contexto particular?

    
por Joshc1107 16.11.2011 / 03:30

6 respostas

103

O lado direito de && só será avaliado se o status de saída do lado esquerdo for zero. || é o oposto: ele avaliará o lado direito apenas se o status de saída do lado esquerdo for diferente de zero. Você pode considerar [ ... ] como um programa com um valor de retorno. Se o teste dentro avaliar true, ele retorna zero; ele retorna diferente de zero.

Exemplos:

$ false && echo howdy!

$ true && echo howdy!
howdy!
$ true || echo howdy!

$ false || echo howdy!
howdy!

Notas extras:

Se você fizer which [ , poderá ver que [ realmente aponta para um programa! Normalmente não é o que roda em scripts; execute type [ para ver o que realmente é executado. Se você quiser usar o programa, apenas forneça o caminho completo da seguinte forma: /bin/[ 1 = 1 .

    
por 16.11.2011 / 03:36
42

Esta é minha folha de dicas:

  • "A; B" Execute A e depois B, independentemente do sucesso de A
  • "A & B" Executar B se A obtiver êxito
  • "A || B" Executar B se um falhar
  • "A &" Execute A no fundo.
por 18.08.2016 / 17:07
20

para expandir a resposta de @ Shawn-j-Goff acima, && é um AND lógico e || é um OR lógico.

Consulte esta parte do Guia Avançado de Script Bash. Alguns dos conteúdos do link para referência do usuário, conforme abaixo.

& &     AND

if [ $condition1 ] && [ $condition2 ]
#  Same as:  if [ $condition1 -a $condition2 ]
#  Returns true if both condition1 and condition2 hold true...

if [[ $condition1 && $condition2 ]]    # Also works.
#  Note that && operator not permitted inside brackets
#+ of [ ... ] construct.

||     OU

if [ $condition1 ] || [ $condition2 ]
# Same as:  if [ $condition1 -o $condition2 ]
# Returns true if either condition1 or condition2 holds true...

if [[ $condition1 || $condition2 ]]    # Also works.
#  Note that || operator not permitted inside brackets
#+ of a [ ... ] construct.
    
por 16.11.2011 / 07:08
9

Da minha experiência, uso o & & e || para reduzir uma declaração if para uma única linha.

Digamos que estamos procurando um arquivo chamado / root / Sample.txt, em seguida, a iteração tradicional seria a seguinte no shell:

if [ -f /root/Sample.txt ]
then
    echo "file found"
else
    echo "file not found"
fi

Estas 6 linhas podem ser reduzidas a uma única linha:

[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"

Ao executar algumas iterações para definir variáveis ou criar arquivos, etc., a vida é mais fácil e o script parece mais simples usando a função de linha única, mas a desvantagem é que se torna um pouco mais difícil implementar vários comandos de um única iteração no entanto, você pode fazer uso de funções.

    
por 21.06.2016 / 02:15
3

Existe uma noção de "corte curto".

Quando (expr1 && expr2) é avaliado - expr2 só é avaliado se exp1 for avaliado como "true". Isso ocorre porque ambos expr1 AND expr2 precisam ser verdadeiros para que (expr1 && expr2) seja verdadeiro. Se expr1 for avaliado como "falso" expr2 NÃO é avaliado (atalho) porque (expr1 && expr2) já está "flase".

Tente o seguinte: presuma que o arquivo F1 exista & arquivo F2 não existe:

( [ -s F1 ] && echo "File Exists" )  # will print "File Exists" - no short cut
( [ -s F2 ] && echo "File Exists" )  # will NOT print "File Exists" - short cut

Similarmente para || (ou) - mas o corte curto é invertido.

    
por 08.01.2015 / 19:47
-1

Os exemplos na resposta de Shawn J. Goff estão corretos, mas a explicação é o contrário. Por favor verifique:

The right side of && will only be evaluated if the exit status of the left side is NONZERO. || is the opposite: it will evaluate the right side only if the left side exit status is ZERO.

    
por 29.09.2016 / 17:14