desenv-web-rp.com

Uso confuso de && e || operadores

Eu estava vasculhando um /etc/rc.d/init.d/sendmail _ (sei que isso quase nunca é usado, mas estou estudando para uma prova) e fiquei um pouco confuso com o && e a || operadores. 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 o && e || operadores para obter respostas com base em testes, mas não consegui desenterrar a documentação referente a esse uso específico desses operadores. Alguém pode explicar o que esses fazem nesse contexto específico?

105
josh-cain

O lado direito de && será avaliada apenas se o status de saída do lado esquerdo for zero (ou seja, verdadeiro). || é o oposto: ele avaliará o lado direito apenas se o status de saída do lado esquerdo for diferente de zero (ou seja, falso).

Você pode considerar [ ... ] para ser um programa com um valor de retorno. Se o teste interno for avaliado como verdadeiro, ele retornará zero; retorna diferente de zero caso contrário.

Exemplos:

$ false && echo howdy!

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

$ false || echo howdy!
howdy!

Notas extras:

Se você fizer which [, você pode ver que [ realmente aponta para um programa! Porém, geralmente não é aquele que roda nos scripts; corre type [ para ver o que realmente é executado. Se você quiser tentar usar o programa, forneça o caminho completo da seguinte maneira: /bin/[ 1 = 1.

159
Shawn J. Goff

Aqui está minha cábula:

  • "A; B" Execute A e, em seguida, B, independentemente do sucesso de A
  • "A && B" Execute B se A tiver êxito
  • "A || B" Execute B se A falhar
  • "A" Execute A em segundo plano.
67
user177073

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

Consulte this parte do Advanced Bash Scripting Guide. Parte do conteúdo do link para referência do usuário, como 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.
30
Tim Kennedy

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

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

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

Essas 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 veloz usando a função if de linha única, o único inconveniente é que fica um pouco mais difícil implementar vários comandos a partir de uma única iteração. você pode fazer uso de funções.

13
syme89

Existe uma noção de "atalho".

Quando (expr1 && expr2) é avaliado - expr2 é avaliado apenas se exp1 avalia como "verdadeiro". Isso ocorre porque ambos expr1 E expr2 tem que ser verdade para (expr1 && expr2) ser verdadeiro. E se expr1 avalia como "false" expr2 NÃO é avaliado (atalho) porque (expr1 && expr2) já é "flase".

Tente o seguinte - assuma o arquivo F1 existe e 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

Da mesma forma para || (ou) - mas o corte curto é revertido.

4
Larry