Eu estava folheando um arquivo /etc/rc.d/init.d/sendmail
(sei que raramente é usado, mas estou estudando para um exame), e fiquei um pouco confuso sobre os operadores &&
e ||
. Eu li onde eles podem ser usados em instruçõ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 uma única linha, como:
[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE" [ -f /usr/sbin/sendmail ] || exit 0
Estes parecem estar usando os operadores &&
e ||
para obter respostas com base em testes, mas não fui capaz de desenterrar documentação a respeito desse uso específico desses operadores. Alguém pode explicar o que eles fazem neste contexto específico?
Resposta
O lado direito de &&
só será avaliado se o status de saída do lado esquerdo for zero (ou seja, verdadeiro). ||
é o oposto: 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; caso contrário, retorna diferente de zero.
Exemplos:
$ false && echo howdy! $ true && echo howdy! howdy! $ true || echo howdy! $ false || echo howdy! howdy!
Observações extras:
Se você fizer which [
, você verá que [
realmente aponta para um programa! No entanto, geralmente não é realmente aquele que é executado em scripts; execute type [
para ver o que realmente é executado. Se você quiser tentar usar o programa, basta fornecer o caminho completo, como então: /bin/[ 1 = 1
.
Comentários
Resposta
Aqui está minha folha de dicas:
- “A; B “Executar A e B, independentemente do sucesso de A
- ” A & & B “Executar B se A for bem-sucedido
- “A || B “Executar B se A falhar
- ” A & “Executar A em segundo plano.
Comentários
- Existem ‘ s alguns paralelos de cálculo lambda interessantes em andamento aqui demonstrados no JavaScript funcional (defina as variáveis em ordem); ” esquerdo (também conhecido como verdadeiro) “:
(a => b => a)
. ” direito (também conhecido como falso) “:(a => b => b)
. ” A; B ” ” e ”(a => b => (() => b())(a()))
. ” A & & B ” ” se sem else (quando) ”(a => b => a()(() => right)(b))
.” A || B ” ” else sem if (a menos) ”(a => b => a()(b)(() => right))
. ” a & & b || c ” ” ifThenElse ”(a => b => c => (unless(when(a)(b))(c))())
. - observe que em bash, left é análogo 0 / string vazia, right análogo é todo o resto.
- E uma única barra vertical?
Resposta
para expandir a resposta de @ Shawn-j-Goff “acima, &&
é um AND lógico e ||
é um OR lógico.
Veja esta parte do Guia de script de Bash avançado. Parte do conteúdo do link para referência do usuário, conforme abaixo.
& & E
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.
Resposta
Pela minha experiência, uso o & & um d || para reduzir uma instrução if a uma única linha.
Digamos que estamos procurando um arquivo chamado /root/Sample.txt, então 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 para criar arquivos etc., a vida é mais fácil e o script parece mais elegante usando a função if de linha única, sua única desvantagem é que se torna um pouco mais difícil implementar vários comandos de uma única iteração, entretanto você pode fazer uso de funções.
Comentários
- Isso é legal. Me lembra do código objc (a == b)? val = 1: val = 2;
- Como posso usar este comando quando quero executar um processo em segundo plano com ” & “? Recebo um erro de sintaxe para
./someScript.sh & && echo 'ok' || echo 'ko'
- No formato:
foo && bar || baz
, sefoo
for bem-sucedido,bar
falhar,baz
será executado, portanto, é sutilmente diferente de umif
declaração. - Devo observar que é possível executar vários comandos em uma linha em
{}
parênteses, usando&&
ou||
, como:pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }
. Também vale a pena mencionar queif..then..else
é um ” reconhecedor ” mais confiável de verdadeiro / condições falsas do que usar&&
e||
.
Resposta
Existe uma noção de “atalho”.
Quando (expr1 && expr2)
é avaliado – expr2
só é avaliado se exp1
for avaliado como” verdadeiro “. Isso ocorre porque expr1
E expr2
precisam ser verdadeiros para (expr1 && expr2)
serem verdadeiros. Se expr1
for avaliado como “false” expr2
NÃO foi avaliado (atalho) porque (expr1 && expr2)
já está “flase”.
Tente o seguinte – suponha que o arquivo F1
existe & 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 curto o corte é invertido.
Comentários
- A lógica geralmente é chamada de ” curto-circuito “. Eu ‘ nunca vi a frase ” atalho ” usada. Menciono isso para ajudar a encontrar referências.
Resposta
Os exemplos na resposta de Shawn J. Goff estão corretas, mas a explicação é inversa. Verifique:
O lado direito de & & só será avaliado se o status de saída do lado esquerdo for NONZERO. || é o oposto: ele avaliará o lado direito apenas se o status de saída do lado esquerdo for ZERO.
Comentários
- Você está ciente de que para shells zero o código de saída é avaliado como verdadeiro e, portanto, o código de saída diferente de zero no lado esquerdo de
&&
faz com que toda a expressão retorne falso ? - Alguém não aprovou suas edições porque não foi sua resposta.Se você acha que alguma resposta está incorreta, você deve votar negativamente e possivelmente deixar um comentário; se você acha que isso requer uma mudança, você deve deixar um comentário. A edição serve para corrigir erros de gramática, formatação e ortografia que não alteram o significado da resposta.
- @countermode I ‘ desculpe, você está certo, Eu pensei que no Linux zero = falso e diferente de zero = verdadeiro (como em C e muitas outras linguagens / ambientes / plataformas). Peço desculpas pelo mal-entendido.
[ ... ]
para ser um programa “, em muitos casos é . Ele ‘ está comumente no arquivo/bin/[
ou/usr/bin/[
.return
status, não booleanos, ondereturn 0
significa sucesso.