
Я заметил, что при использовании tcpdump
для чтения файла pcap tcpdump
команда каким-то образом умудряется выводить информацию на мою консоль, даже когда я перенаправляю и STDOUT, и STDERR. Как мне предотвратить tcpdump
вывод " reading from file capture, link type EN10MB (Ethernet)
" каждый раз при запуске?
Например, следующая команда выводит строку, хотя я не ожидал ее:
$ tcpdump -A -r capture.pcap | grep interesting-string > /dev/null 2>&1
reading from file capture.pcap, link-type EN10MB (Ethernet)
Я хотел бы предотвратить появление этой строки, поскольку она добавляет ненужный и нежелательный шум в вывод скрипта. Я проверил страницу руководства и не увидел опции, которая бы предотвращала появление этого сообщения. Я искал в Интернете способы подавления вывода, не захватываемого STDOUT и STDERR, и нашел несколько результатов, но ни один из них я не мог бы понять или использовать в этом контексте.
решение1
Я думаю, что вы хотите поместить перенаправление вывода перед конвейером, чтобы оно применялось к выводу tcpdump, а не grep.
tcpdump -A -r capture.pcap 2>&1 | grep interesting-string > /dev/null
решение2
Более подробная версия ответа Спиффа:
Если у вас есть трубопровод
command1 | command2
затем стандартный вывод команды 1, нонетего стандартная ошибка перенаправляется в канал, идущий к стандартному вводу команды 2.
Так что если вы это сделаете
command1 | command2 >/dev/null 2>&1
который отправляет стандартный вывод команды 2 в /dev/null
, а стандартную ошибку — в то же место, куда был отправлен стандартный вывод (так что /dev/null
в этом случае она тоже попадает туда), но он ничего не делает со стандартной ошибкой команды 1 и оставляет стандартный вывод команды 1 направленным на стандартный ввод команды 2.
Однако команда
command1 2>/dev/null | command2 >/dev/null 2>&1
отправит стандартный вывод команды 1 на стандартный ввод команды 2, стандартную ошибку команды 1 на /dev/null
, а стандартный вывод и ошибку команды 2 на /dev/null
, и команда
command1 2>&1 | command2 >/dev/null 2>&1
отправит стандартный вывод команды 1 на стандартный ввод команды 2, стандартную ошибку команды 1 в то же место, что и стандартный вывод команды 1, т. е. на стандартный ввод команды 2, а стандартный вывод и ошибку команды 2 отправит в /dev/null
.
Так, например
tcpdump -A -r capture.pcap 2>&1 | grep interesting-string > /dev/null 2>&1
приведет grep
к тому, что будут видны как стандартный вывод, так и ошибка tcpdump
(то есть он увидит reading from file...
сообщение и сопоставит его, если интересующая его строка является его частью), и отправит стандартный вывод и ошибку в grep
, /dev/null
поэтому он не должен выдаватьлюбойвывод, он должен просто выдать статус выхода grep
(что, как я предполагаю, и является вашим намерением, т. е. все, что вы хотите знать, это является ли интересующая строка частью какого-либо из пакетов).
Кстати, если вы используете , grep
чтобы узнать, является ли заданная строка частью входных данных или нет, и не хотите никаких выходных данных, попробуйте использовать , grep -q
если ваша версия grep
поддерживает это; это будет работать быстрее, потому что
grep
не нужно тратить процессорное время на запись в/dev/null
;grep
может завершить работу сразу же, как только увидит строку, поэтому не будет тратить больше процессорного времени на чтение, а затем tcpdump завершит работу с ошибкой «Закрытый канал» послеgrep
завершения иэтоне будет больше тратить процессорное время или пропускную способность диска/SSD на чтение из файла.
(Старые версии grep
использовали -s
для той же цели, но стандарт UNIX гласит, что это -q
, и большинство UNIX и UNIX-подобных систем сейчас делают это; GNU grep
, например, использует -q
.)