Qual é o objetivo de "&&" em um comando shell?

Respostas:

399

&&permite que você faça algo com base em se o comando anterior foi concluído com êxito - é por isso que você tende a vê-lo encadeado como do_something && do_something_else_that_depended_on_something.

girasquid
fonte
391

Além disso, você também tem ||qual é o lógico ou e também ;qual é apenas um separador que não se importa com o que aconteceu com o comando antes.

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Alguns detalhes sobre isso podem ser encontrados aqui Listas de comandos no Manual do Bash.

plundra
fonte
5
Talvez você gostaria de adicionar false && echo "Will not be printed".
MTSan
112

linha de comando - qual é o objetivo &&?

Com casca, quando você vê

$ command one && command two

a intenção é executar o comando que segue &&apenas se o primeiro comando for bem-sucedido. Isso é idiomático dos shells Posix, e não apenas encontrado no Bash.

Ele pretende impedir a execução do segundo processo se o primeiro falhar.

Você pode perceber que eu usei a palavra "intenção" - por uma boa razão. Nem todos os programas têm o mesmo comportamento; portanto, para que isso funcione, você precisa entender o que o programa considera uma "falha" e como ele lida com isso lendo a documentação e, se necessário, o código fonte.

Seu shell considera um valor de retorno 0 para true, outros números positivos para false

Os programas retornam um sinal ao sair. Eles devem retornar 0 se sair com êxito ou maior que zero se não o fizerem. Isso permite uma quantidade limitada de comunicação entre processos.

O &&é referido como AND_IFna gramática shell POSIX , que é parte de uma and_orlista de comandos, que também inclui o ||que é umOR_IF com a semântica semelhantes.

Símbolos gramaticais, citados na documentação:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

E a gramática (também citada na documentação), que mostra que qualquer número de AND_IFs ( &&) e / ou OR_IFs ( ||) pode ser unido (como and_ordefinido recursivamente):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Ambos os operadores têm precedência igual e são avaliados da esquerda para a direita (eles são deixados associativos). Como dizem os documentos:

Uma AND-ORlista é uma sequência de um ou mais pipelines separados pelos operadores "&&"e "||".

Uma lista é uma sequência de um ou mais e-ou listas separadas por os operadores ';'e '&'e opcionalmente terminado por ';', '&'ou.

Os operadores "&&"e"||" devem ter precedência igual e devem ser avaliados com associatividade à esquerda. Por exemplo, os dois comandos a seguir gravam apenas a barra na saída padrão:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. No primeiro caso, o false é um comando que sai com o status de 1

    $ false
    $ echo $?
    1

    o que significa echo fooque não roda (ou seja, curto-circuito echo foo). Então o comando echo baré executado.

  2. No segundo caso, true sai com um código de 0

    $ true
    $ echo $?
    0

    e, portanto, echo foonão é executado, então echo baré executado.

Aaron Hall
fonte
31

Um uso bastante comum para '&&' é compilar software com ferramentas automáticas. Por exemplo:

./configure --prefix=/usr && make && sudo make install

Basicamente, se a configuração for bem-sucedida, o make será executado para compilar e, se for bem-sucedido, o make será executado como root para instalar o programa. Eu uso isso quando tenho quase certeza de que tudo vai funcionar e isso me permite fazer outras coisas importantes, como olhar para o stackoverflow e não 'monitorar' o progresso.

Às vezes eu me empolgo muito ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Eu faço isso quando, por exemplo, fazendo um linux a partir da caixa do zero.

Nigel Atkinson
fonte
2
Bom no REPL, mas para scripts eu preferiria o set -o errexitBash.
Franklin Yu
19

&&comandos de strings juntos. Os comandos sucessivos somente são executados se os anteriores tiverem êxito.

Similarmente, || permitirá que o comando sucessivo seja executado se o anterior falhar.

Consulte Programação do Bash Shell .

Dean Burge
fonte
8

Veja o exemplo:

mkdir test && echo "Something" > test/file

O Shell tentará criar o diretório teste, em seguida, somente se tiver sido bem-sucedido , tentará criar o arquivo dentro dele.

Portanto, você pode interromper uma sequência de etapas se uma delas falhar.

alno
fonte
8

É para executar uma segunda instrução se a primeira instrução terminar com sucesso. Como uma declaração if:

 if (1 == 1 && 2 == 2)
  echo "test;"

Suas primeiras tentativas se 1 == 1, se isso for verdade, verifica se 2 == 2

usuario
fonte
11
Alguém poderia explicar por que isso foi rebaixado para os usuários que se depararam com a pergunta?
user3243242
11
@ user3243242 não é errado, apenas um mau exemplo para ilustrar o uso de&&
dan
É uma ótima visão de como os iftestes funcionam no bash. Eu nunca pensei nisso como uma cadeia de comandos de comparação, quebrando quando algum deles falhou. Então você tem o meu upvote :)
Pirk
11
A conseqüência é que você pode obter o comportamento oposto usando ||, para encadear comandos até que um deles seja bem-sucedido: eei || leu || uie || echo prout3 || echo "never executed"
PiRK 24/11
7

command_1 && command_2: execute command_2 apenas quando command_1 for executado com sucesso.

command_1 || command_2: execute command_2 apenas quando command_1 não for executado com êxito.

Parece semelhante à forma como uma condição 'if' é executada em uma linguagem de programação convencional, como, na if (condition_1 && condition_2){...}condição_2 será omitida se a condição_1 for falsee na if (condition_1 || condition_2){...}condição_2 será omitida se a condição_1 for true. Veja, é o mesmo truque que você usa para codificar :)

Xiaonin Li
fonte
Não sei o que você quer dizer com 'exatamente o oposto', mas $ echo '1' || o eco '2' imprime apenas '1'. e $ wrong_command || o eco '2' imprime uma mensagem de erro e '2' na próxima linha. Você poderia explicar um pouco mais sobre o que acha errado?
Xiaonin Li
ho cara, eu certamente estava muito cansado ontem. desculpe por isso, foi só me: / Eu preciso de você editar algo em você responda se você quer i upvote (para tornar a sua resposta 0, agora stackoverflow pedir para editar por isso não posso)
arount
@Ount, está tudo bem, não se preocupe. Então acabei de enviar uma edição. então você é capaz de remover o voto negativo agora?
Xiaonin Li
Sim, mais uma vez, sinto muito, realmente
arount
0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

Quando o programa verifica o comando, o programa cria um número chamado código de saída; se as duas condições forem verdadeiras, o código de saída será zero (0); caso contrário, o código de saída será um número positivo. somente ao exibir Igual se o código de saída for produzido zero (0), o que significa que ambas as condições são verdadeiras.

Amin
fonte
Bem-vindo ao stackoverflow. Verifique se o seu snippet de código funciona antes de postar aqui. Você tem que corrigi-loif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu
11
Obrigado @ZhengQu por seu comando, foi feito.
Amin