Existe uma diferença entre `;` e `&&` e `|`?

Existe uma diferença entre `;` e `&&` e `|`?

Quando você deseja executar vários comandos ;, você pode usar &&e|

Assim: killall Finder; killall SystemUIServer, cd ~/Desktop/ && rm CachesOu: man grep | man catpor exemplo.

Mas, existe uma diferença |entre ;e &&? Se sim, qual é a diferença?

Responder1

  • ;: comandos separados por a ; são executados sequencialmente. O shell espera que cada comando termine por sua vez.

  • &&: o comando after &&é executado se, e somente se, o comando before &&retorna um status de saída zero. Você pode pensar nisso como ANDum operador.

  • |: um cano. Na expressão command1 | command2A saída padrão do comando1 é conectada por meio de um tubo à entrada padrão do comando2.

Existem mais operadores de controle semelhantes, que vale a pena mencionar:

  • ||: o comando after ||é executado se, e somente se, o comando before ||retornar um status de saída diferente de zero. Você pode pensar nisso como ORum operador. Observe que |são ||animais completamente diferentes.

  • &: o shell executa o comando finalizado por &em segundo plano, não espera o comando terminar e retorna imediatamente o código de saída 0. Mais uma vez, &não tem nada a ver com &&.

  • |&: uma abreviatura para 2>&1 |, ou seja, a saída padrão e o erro padrão do comando1 são conectados à entrada padrão do comando2 através do tubo.

Além disso, se você usar zsh, também poderá iniciar o comando com &|ou &!. Neste caso o job é imediatamente rejeitado, após a inicialização ele não tem lugar na tabela de jobs.

Responder2

Considere dois comandos Ae B. Quando você escreve

A | B

Ae Bsão executados em paralelo, e a saída padrão de Aé enviada como entrada padrão de B.

Quando você escreve

A; B

Aé executado e, em seguida, Bé executado (a menos que set -etenha sido usado e Atermine com um status de saída diferente de zero; nesse caso, o shell termina logo após A).

Quando você escreve

A && B

Aé executado e, em seguida, Bserá executado somente se Afor finalizado com sucesso (status de saída zero). Este formulário pode ser mais seguro que o anterior, por exemplo, com

cd some_dir && rm file*

O &&garante que os arquivos corretos sejam removidos, ou seja, os arquivos serão removidos somente se o cdprocedimento for bem-sucedido.

Responder3

As outras respostas já explicam |e , então acrescentarei algo adicional que você não pediu &&explicitamente :.;||

A || B

Aé executado e Bsó é executado se Afalhar. Isso é útil para reagir a condições de erro:

martin@martin ~ % rm doesnotexist 2>/dev/null || echo "failed to delete file"
failed to delete file

(Isso 2>/dev/nullé necessário para ocultar a própria mensagem de erro rm.)

Responder4

Ninguém parece estar explicando por que você usaria cada um deles, dados seus exemplos reais. Vou tentar:

killall Finder; killall SystemUIServer

Um comando como esse killallpode levar algum tempo para ser executado. Usando o ponto e vírgula, você pode dar os dois comandos ao mesmo tempo e depois fazer outra coisa enquanto espera. Dessa forma você não precisa esperar duas vezes (uma para cada comando).

cd ~/Desktop/ && rm Caches

Você deseja remover o diretório ~/Desktop/Cachese acabar no diretório ~/Desktop. O que você não quer fazer é remover o diretório Caches do diretório atual (antes de alterá-lo). Então você usa &&para verificar se a mudança de diretório foi bem-sucedida antes de executar o comando de remoção.

man grep | man cat

Isso não faz sentido para mim. O mancomando não processa a entrada, portanto, canalizar coisas para ele não fará nada. Talvez você quis dizer

man grep || man cat

Isso tentaria encontrar a página de manual para grepe, se não conseguisse, mostraria a página de manual para cat. Ou possivelmente você quis dizer

man grep | cat

Isso seria usado catpara exibir a página de manual em vez do pager (normalmente less). O |redireciona a saída manpara o comando cat(que apenas despeja tudo na tela). Isso pode ser útil em uma GUI onde você pode usar a barra de rolagem para ir e voltar no arquivo em vez de usar os comandos do teclado em menos.

Nota: se você quiser saber o que ; && | ||fazer nos casos mais gerais, sugiro dar uma olhada na resposta de jimmij. Estou apenas tentando explicar o que está acontecendo nos exemplos da pergunta.

informação relacionada