![Перенаправление вывода Linux не работает с awk](https://rvso.com/image/1337795/%D0%9F%D0%B5%D1%80%D0%B5%D0%BD%D0%B0%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B0%20Linux%20%D0%BD%D0%B5%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0%D0%B5%D1%82%20%D1%81%20awk.png)
Я пытаюсь написать хороший 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