Я пытаюсь написать хороший CSV-файл, основанный на некоторых выводах сверху. Я переформатирую вывод с помощью 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 из топ-процесса. Что я делаю неправильно?

2 ответа2

1

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

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

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

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

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

0

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .