Как перенаправить вывод любой команды?

14

Я пытаюсь написать простой скрипт для мониторинга моего состояния сети, без pingвывода всех данных:

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

Проблема в том, что когда я не подключен, я все еще получаю сообщение об ошибке в моем выводе:

ping: unknown host google.com
offline

Как я могу сохранить это сообщение об ошибке в моем выводе?

operalala
источник

Ответы:

28

Когда вы бежите:

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

По сути, вы только перенаправляете выходные данные потока 1 (т.е. stdout) в /dev/null.

Это хорошо, когда вы хотите перенаправить вывод, который получается при нормальном выполнении программы. Однако, если вы также хотите перенаправить вывод, вызванный всеми ошибками, предупреждениями или сбоями, вам также следует перенаправить stderrпоток или стандартную ошибку в /dev/null.

Одним из способов сделать это является добавление номера потока, который вы хотите перенаправить, к оператору перенаправления, >например так:Command 2> /dev/null

Следовательно, ваша команда будет выглядеть так:

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

Но обратите внимание, что мы уже перенаправили один поток на /dev/null. Почему бы просто не воспользоваться контрейлером на том же перенаправлении? Bash позволяет нам сделать это, указав номер потока, на который будет перенаправляться. 2>&1,

Обратите внимание на &символ после оператора перенаправления. Это говорит оболочке, что следующим будет не имя файла, а идентификатор для выходного потока.

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

Будьте осторожны с операторами перенаправления, их порядок очень важен. Если вы перенаправили в неправильном порядке, вы получите неожиданные результаты.

Другой способ достичь полной тишины - перенаправить все выходные потоки, /dev/nullиспользуя этот ярлык: &>/dev/null(или перенаправить в файл журнала с помощью &>/path/to/file.log).

Следовательно, напишите вашу команду как:

ping -q -c 1 google.com &> /dev/null && echo online || echo offline
darnir
источник
1
Ага &>/dev/nullэто так. Спасибо всем за мгновенную помощь!
operalala
4
Be careful with the redirection operators, their order matters a lot., но вы не включили пример фактического использования2>&1
Izkata
Я забыл добавить это! Отредактированный ответ, чтобы отразить пример. Когда у меня будет немного больше времени, я объясню, как работает порядок.
Дарнир
9

Вам нужно перенаправить как стандартный вывод ( >или 1>), так и стандартную ошибку ( 2>):

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

или перенаправить одно на другое:

ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline
Тердон
источник
8
$ ping -q -c 1 google.com > /dev/null 2>&1 && echo online || echo offline

Примеры

$ 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

Ускорение пинга

В зависимости от вашей pingреализации вы можете быть ограничены одним счетом -c 1. Некоторые реализации позволят вам пойти ниже этого, но вам, по сути, придется ждать неудачных поисков до истечения времени ожидания. Поэтому вместо использования pingвы можете использовать fingвместо этого.

медлительность провала пинга

$ 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

финг намного быстрее проваливается

$ 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
источник
1
Я предпочел бы использовать timeкоманду, чем вручную вычислять разницу во времени с date:time { fing -p googleadf.com > /dev/null 2>&1 && echo online || echo offline; }
Русланом
@Ruslan - спасибо, я сделал это так, как я хотел, чтобы вывод date. ИМО, кому-то еще проще прочитать сгенерированный результат.
СЛМ