
Quando você deseja executar vários comandos ;
, você pode usar &&
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?
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 comoAND
um operador.|
: um cano. Na expressãocommand1 | command2
A 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 comoOR
um 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 para2>&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 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 entrada padrão de B
.
Quando você escreve
A; B
A
é executado e, em seguida, B
é executado (a menos que set -e
tenha sido usado e A
termine 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, B
será executado somente se A
for 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 cd
procedimento 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 B
só é executado se A
falhar. 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 killall
pode 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/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). 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 man
comando 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 grep
e, se não conseguisse, mostraria a página de manual para cat
. Ou possivelmente você quis dizer
man grep | cat
Isso seria usado cat
para exibir a página de manual em vez do pager (normalmente less
). O |
redireciona a saída man
para 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.