Перенаправление вывода Linux не работает с awk

Перенаправление вывода Linux не работает с awk

Я пытаюсь написать хороший csv-файл на основе некоторого вывода из top. Я переформатирую вывод с помощью awk следующим образом:

top -b | nawk '/Cpu/ || /Tasks/ { if($1 ~ /Cpu/) { printf "%s,",$3 } else { printf "\n" } }'

Это работает отлично. Теперь я хочу сохранить вывод в файл. Я думаю, что использование > output.logдолжно сработать:

top -b | nawk '/Cpu/ || /Tasks/ { if($1 ~ /Cpu/) { printf "%s,",$3 } else { printf "\n" } }' > output.log

Однако это просто приводит к пустому файлу, когда я нажимаю Ctrl-C из верхнего процесса. Что я делаю не так?

решение1

Стандартная библиотека ввода-вывода Unix («stdio») определяет, в какой тип объекта (приемник данных) она пишет. Если она обнаруживает терминал (т. е. окно), она записывает данные немедленно, когда программа запрашивает их. Однако при записи в файл библиотека ввода-вывода буферизует данные и записывает их блоками по 512 (или более) байт за раз. Конечно, она очищает буфер (записывая частичный блок) при завершении вызывающей программы — если она завершается чисто. Ненормальное завершение (вызванное Ctrl+ C) может оставить вас с неполным выходным файлом.

Чтобы исправить, попробуйте:

top -b | ( trap "" 2; nawk '(ваша nawkкоманда)' > output.log)`

Команда trapсделает nawkкоманду невосприимчивой к Ctrl+ C. (Конечно, Ctrl+ Cвсе равно убьет topпроцесс и nawkзавершится (корректно!), когда получит сигнал конца файла (EOF) на канале.

P.S. Это предполагает (требует), что вы используете bash-совместимую bashоболочку.

решение2

Top продолжает работать. Вы хотите запустить его ограниченное количество раз. Используйте опцию -n. например:

top -b -n 1 | awk '{ ... }'

В качестве альтернативы вы можете выйти из top, когда захотите, с помощью C-\. Использование Cc прервет его и разорвет конвейер преждевременно (до того, как awk что-нибудь получит).

$ top -b | cat -n > moo ; wc -l moo
^\Quit
352 moo

Связанный контент