
У меня к вам фиктивный вопрос, я пытаюсь извлечь несколько строк из файла, начинающегося со специальной строки символов, и скопировать их в файл. Я попробовал:
cat /dev/ttyACM0 | grep "something" > essai
Файл создан, но в нем ничего нет!
решение1
Для эффективности grep и многие другие команды используютбуферизованный ввод-вывод, то есть они считывают большие блоки данных за один раз (а не, скажем, по одному символу за раз) и не выводят данные, пока не накопится определенное количество (а не, скажем, не записывают по строке или по символу за раз)
Но когда ввод программы осуществляется с терминала (например, с последовательного порта), операционная система оказывает программе услугу и возвращает данные по одной строке за раз (программа может изменить это, переведя терминал в режимсыройилинеканонический режим; большинство этого не делают).
И когда программа используетстдиостандартный вывод на терминал (в документации это называется «интерактивным устройством») по умолчанию буферизуется строками, но вывод в файл или канал буферизуется полностью.
Программа, использующая библиотеку stdio, может выбрать полную буферизацию, построчную буферизацию или отсутствие буферизации, вызвавsetvbuf
. Он также может позвонитьfflush
заставить писать, когда захочется.
GNU grep принимает--line-buffered
вариант, который запуститследующий кодв функции, которая выводит соответствующую строку:
if (line_buffered)
fflush (stdout);
Собираем все части вместе:
С помощью этой команды:
cat /dev/ttyACM0 | grep "something" > essai
cat
будет читать по одной строке из /dev/ttyACM0
. После того, как он накопит несколько килобайт вывода, он будет записывать в канал. Он будет повторять это до тех пор, пока чтение не вернет счетчик ноль или не завершится неудачей (что, вероятно, не произойдет, пока последовательный порт не перейдет в автономный режим).
grep
будет читать несколько килобайт за раз из канала, и после того, как он накопит несколько килобайт вывода, он запишет в essai
файл. Он будет повторять это до тех пор, пока чтение не вернет счетчик ноль или не завершится неудачей, что произойдет, если и когда процесс cat
завершится.
Таким образом, вы не увидите ничего в essai
файле, пока grep
не найдете несколько килобайт совпадающих строк.
Чтобы вывод записывался в файл быстрее, вы можете указать GNU grep следующую опцию:
grep --line-buffered < /dev/ttyACM0 > essai
Поскольку чтение осуществляется с последовательного порта, оно будет буферизировано построчно, а --line-buffered
опция также сделает буферизированной и выходную строку.