Como redirecionar a saída de qualquer comando?

14

Estou tentando escrever um script simples para monitorar o status da minha rede, sem toda pinga saída de:

ping -q -c 1 google.com > /dev/null && echo online || echo offline

O problema é que, quando não estou conectado, ainda recebo uma mensagem de erro na minha saída:

ping: unknown host google.com
offline

Como posso manter essa mensagem de erro fora da minha saída?

operalala
fonte

Respostas:

28

Quando você executa:

ping -q -c 1 google.com > /dev/null && echo online || echo offline

Você está basicamente redirecionando apenas a saída do fluxo 1 (ou seja stdout) para /dev/null.

Isso é bom quando você deseja redirecionar a saída produzida pela execução normal de um programa. No entanto, caso você também deseje redirecionar a saída causada por todos os erros, avisos ou falhas, você também deve redirecionar o stderrfluxo ou Erro Padrão para /dev/null.

Uma maneira de fazer isso é preceder o número do fluxo que você deseja redirecionar para o operador de redirecionamento, >assim:Command 2> /dev/null

Portanto, seu comando seria semelhante a:

ping -q -c 1 google.com > /dev/null 2> /dev/null && echo online || echo offline

Mas observe que já redirecionamos um fluxo para /dev/null. Por que não simplesmente pegar carona no mesmo redirecionamento? O Bash nos permite fazer isso especificando o número do fluxo para o qual redirecionar. 2>&1.

Observe o &caractere após o operador de redirecionamento. Isso informa ao shell que o que aparece a seguir não é um nome de arquivo, mas um identificador para o fluxo de saída.

ping -q -c 1 google.com > /dev/null 2>&1  echo online || echo offline

Tenha cuidado com os operadores de redirecionamento, a ordem deles é muito importante. Se você redirecionar na ordem errada, você terá resultados inesperados.

Outra maneira pela qual você pode obter um silêncio completo é redirecionando todos os fluxos de saída para /dev/nullusar este atalho: &>/dev/null(ou redirecione para um arquivo de log com &>/path/to/file.log).

Portanto, escreva seu comando como:

ping -q -c 1 google.com &> /dev/null && echo online || echo offline
darnir
fonte
1
Ah, &>/dev/nullsim. Obrigado a todos pela ajuda instantânea!
operalala 28/01
4
Be careful with the redirection operators, their order matters a lot., mas você não incluiu um exemplo de uso real2>&1
Izkata 28/01
Eu tinha esquecido de adicionar isso! Resposta editada para refletir o exemplo. Quando tiver um pouco mais de tempo, explicarei como a encomenda também funciona.
darnir
9

Você precisa redirecionar a saída padrão ( >ou 1>) e o erro padrão ( 2>):

ping -q -c 1 google.com > /dev/null 2>/dev/null && echo online || echo offline

ou, redirecione um para o outro:

ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline
terdon
fonte
8
$ ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline

Exemplos

$ ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline
online

$ ping -q -c 1 googleadf.com > /dev/null 2>&1 && echo online || echo offline
offline

Acelerando o ping

Dependendo da sua pingimplementação, você pode estar limitado a uma única contagem -c 1. Algumas implementações permitem que você fique abaixo disso, mas você basicamente precisa aguardar o tempo limite das pesquisas ruins. Então, em vez de usar, pingvocê pode usar fing.

lentidão do ping falhando

$ date; ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:51:10 EST 2014
online
Tue Jan 28 13:51:10 EST 2014

$ date; ping -q -c 1 googleadf.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:51:15 EST 2014
offline
Tue Jan 28 13:51:25 EST 2014

dedo é muito mais rápido para falhar

$ date; fing -p google.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:49:21 EST 2014
online
Tue Jan 28 13:49:22 EST 2014

$ date; fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; date
Tue Jan 28 13:49:35 EST 2014
online
Tue Jan 28 13:49:38 EST 2014
slm
fonte
1
Prefiro usar o timecomando do que calcular manualmente a diferença de tempo com date:time { fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; }
Ruslan
@Ruslan - obrigado, eu fiz dessa maneira porque eu queria a saída de date. É mais fácil, IMO, para outra pessoa ler a saída gerada.
slm