Existe diferença entre ';' e '&&' e '|' [duplicado]

16

Quando você quiser executar vários comandos, use ; , && e |

Assim: killall Finder; killall SystemUIServer , cd ~/Desktop/ && rm Caches Ou: man grep | man cat , por exemplo.

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

    
por DisplayName 06.10.2014 / 00:37

5 respostas

53
  • ; : comandos separados por ; são executados sequencialmente. O shell aguarda que cada comando termine por vez.

  • && : comando após && ser executado se, e somente se, comando antes de && retornar um status de saída igual a zero. Você pode pensar nisso como AND operator.

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

Existem mais operadores de controle similares, vale a pena mencionar:

  • || : comando após || ser executado se, e somente se, comando antes de || retornar um status de saída diferente de zero. Você pode pensar nisso como OR operator. Por favor, note que | e || são animais completamente diferentes.

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

  • |& : uma abreviação de 2>&1 | , ou seja, a saída padrão e o erro padrão do comando1 são conectados à entrada padrão do comando2 por meio do canal.

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

    
por 06.10.2014 / 00:47
10

Considere dois comandos A e B . Quando você escreve

A | B

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

Quando você escreve

A; B

A é executado, então B é executado (a menos que set -e tenha sido usado e A termine com um status de saída diferente de zero, caso em que o shell termina logo após A ). / p>

Quando você escreve

A && B

A é executado, então B é executado somente se A foi finalizado com sucesso (status de saída zero). Esta forma pode ser mais segura que a anterior, por ex. com

cd some_dir && rm file*

O && certifica-se de que os arquivos corretos foram removidos, ou seja, os arquivos serão removidos somente se o cd for bem-sucedido.

    
por 06.10.2014 / 00:47
6

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

A || B

A é executado e, em seguida, B é executado apenas se A falhar. Isso é útil para reagir em condições de erro:

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

(O 2>/dev/null é necessário para ocultar a mensagem de erro do rm em si.)

    
por 06.10.2014 / 00:51
3

Todos os três são bastante diferentes um do outro, especialmente | .

  • | : Primeiro de tudo, é chamado de 'pipe' e pode ser usado para redirecionar a saída de um programa para o outro. Seu exemplo não fará nada significativo, porque o homem não usa a entrada padrão para nada. Um exemplo mais significativo seria man grep | grep -- -v , que encontrará '-v' na saída de man grep

  • ; : o ponto-e-vírgula pode ser usado em vez de uma nova linha, para que as coisas ocupem menos espaço.

  • && : o operador "e" comercial "e" é um operador AND booleano que significa que o comando após o && ser executado se, e somente se, o comando no lado esquerdo retornar true, o que nos sistemas UNIX significa que ele retornou com o código de saída 0.

por 06.10.2014 / 00:51
2

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

killall Finder; killall SystemUIServer

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

cd ~/Desktop/ && rm Caches

Você deseja remover o diretório ~/Desktop/Caches e 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). Portanto, use && para verificar se a alteração do diretório foi bem-sucedida antes de executar o comando remove.

man grep | man cat

Isso não faz sentido para mim. O comando man não processa entrada, portanto, canalizar as coisas para ele não fará nada. Talvez você quisesse dizer

man grep || man cat

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

man grep | cat

Isso usaria cat para exibir a página man em vez do pager (normalmente less ). O | redireciona a saída de man para o comando cat (que apenas despeja tudo na tela). Isso pode ser útil em uma GUI na qual 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 que você analise a resposta de jimmij. Eu só estou tentando explicar o que está acontecendo nos exemplos da questão.

    
por 06.10.2014 / 05:00

Tags