Qual é o melhor: using; ou && para executar vários comandos em uma linha?

427

Nos tutoriais e instruções, muitas vezes vejo comandos combinados. Por exemplo,

sudo apt-get update && sudo apt-get install pyrenamer

Parece haver quatro possíveis conectores: &, &&, ||e ;. Embora o & conector seja claro para mim (ele envia um processo para o plano de fundo e deixa o terminal disponível), não está claro qual é a diferença entre &&e ;. E eu não sabia ||até o comentário de Kaya.

As perguntas a seguir lidam com a diferença entre os dois conectores, mas principalmente nos comentários:

Então, aqui estão algumas perguntas relacionadas:

  1. Qual é a diferença entre ;e &&?
  2. Quando você deve usá-los, respectivamente? Seria bom ver alguns casos de uso: se eu quiser executar um comando e depois desligar o computador, qual conector devo escolher?
  3. Quais são suas vantagens e perigos ? Robie Basak menciona em um comentário a esta resposta que um comando como cd /somewhere_else; rm -Rf *pode ter consequências destrutivas se o primeiro elemento da cadeia de comando falhar, por exemplo.
  4. Se relevante, de onde eles vêm?
don.joey
fonte
7
Há outro conector que você pode não encontrar: ||é o mesmo que &&exceto que ele só executa o segundo comando se o primeiro sair com um status diferente de zero (sem êxito).
Kaya
4
Observe também que a execução do seu script set -einterromperá o script com falha, como se todos os comandos estivessem conectados &&.
choroba
stackoverflow.com/questions/3573742/…
Ciro Santilli escreveu:
3
Ninguém respondeu Qn 4 ... Suspeito do comportamento de && e || foi inspirado na linguagem de programação C. No caso de (x && y), se x é avaliado como falso, toda a expressão deve ser falsa para que um compilador possa otimizar a avaliação de y, caso seja caro. Os modernos padrões C e C ++ realmente exigem essa otimização, para que os programas possam assumir com segurança que y não será avaliado se x for falso. Por exemplo, (ptr && ptr-> days> 31) não trava, mesmo que ptr seja nulo. Também em C, as instruções terminam com; independentemente de haver outra declaração na mesma linha ou não.
Kevin

Respostas:

771

Folha de dicas:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.
Jack
fonte
19
E, é claro A & B &: Execute A em segundo plano, depois execute B em segundo plano (independentemente do sucesso) e retorne o controle ao shell. Isso geralmente funciona da mesma forma que executar os dois processos ao mesmo tempo.
Expiação limitada
4
é possível dizer: execute a em segundo plano, seguido por b em segundo plano somente se funcionou? (Eu acho que &&&?)
user230910
15
@ user230910: isso seria (A && B) &.
leftaroundabout
5
Você pode fazer referência a um documento oficial para isso?
Jaime Hablutzel
@Jack Quando executado a partir do Cronjob, não segue completamente essa regra, tem alguma idéia do porquê? Para um arquivo python
CodeGuru 25/10
77

&&somente executa o segundo comando se o primeiro saiu com o status 0 (foi bem-sucedido). ;executa os dois comandos, mesmo que o primeiro saia com um status diferente de zero.

Seu exemplo com &&pode ser parafraseado equivalentemente como

if sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi
choroba
fonte
Obrigado. Atualizei a pergunta para garantir que as diferentes subquestões sejam facilmente distinguíveis.
don.joey
5
@ Privado: você deve usar ;se o segundo comando não precisar do anterior para ter sucesso.
choroba
31

O uso ;executará os comandos independentemente de o primeiro comando ser bem-sucedido ou não.

usando &&execute o segundo comando somente quando o primeiro comando for executado com sucesso (status 0).

Ambos são usados ​​em diferentes perspectivas. Como para um processo mais longo, digamos que para uma instalação você precise compilá-lo e instalá-lo. você deveria make && make install. Portanto, a instalação será executada apenas se for makebem-sucedida.

Portanto, para comandos dependentes, você deve usar &&

Torcer bash ou comandos com comandos independentes usam ;

Portanto, se você deseja desligar o computador, até o primeiro trabalho falhou ;, mas se desejar, no sucesso completo do primeiro trabalho, inicie o desligamento&&

Web-E
fonte
14

a ; bexecutará b, independentemente do status de saída de a. a && bexecutará b apenas se a tiver êxito.

Isso é necessário e suficiente para responder às três primeiras perguntas. Em particular, o 2 é muito amplo e não pode receber "uma" resposta definitiva - sua melhor aposta é decidir caso a caso.

Quanto à quarta pergunta: eles são sintaxe do Bash .

Também não há perigo intrínseco ao usar. Mais uma vez, a definição acima é suficiente. Isso implica que você escreverá &&quando btiver efeitos indesejados, se anão for bem-sucedido. Não há necessidade de mais regras ou explicações, IMHO.

ignis
fonte
1

UMA; B # Execute A e, em seguida, B, independentemente do sucesso de A

A && B # Execute B se e somente se A tiver êxito

A || B # Execute B se e somente se A falhar

A & # Execute A em segundo plano.

Uma regra muito boa. Eu acrescentaria que, em alguns casos, usar esses comandos em um subshell faz sentido quando queremos considerá-los como uma única unidade ou não queremos combinar alguns resultados de operações com o shell atual.

Exemplos:

-concatenar a saída de dois comandos:

(ls foo; ls bar) > single-result.txt

- entrando em um diretório e executando um comando a partir daí, sem alterar o diretório atual do shell:

(cd target-directory && jar -xf ../my-jar)
davidxxx
fonte