Это просто, что, когда stdout не является терминалом, вывод буферизуется.
И когда Вы нажимаете Ctrl-C, тот буфер потерян, поскольку/если он еще не был записан.
Вы получаете то же поведение с чем-либо использование stdio
. Попробуйте, например:
grep . > file
Введите несколько непустых строк и нажмите Ctrl-C, и Вы будете видеть, что файл пуст.
С другой стороны, тип:
xinput test 10 > file
И введите достаточно на клавиатуре для буфера для получения сытыми (по крайней мере, 4k ценность ouput), и Вы будете видеть, что размер файла растет блоками 4k за один раз.
С grep
, можно ввести Ctrl-D для grep
выходить корректно сбросив его буфер. Для xinput
, Я не думаю, что существует такая опция.
Отметьте это по умолчанию stderr
не буферизуется, который объясняет, почему Вы получаете другое поведение с fprintf(stderr)
Если, в xinput.c
, Вы добавляете a signal(SIGINT, exit)
, это, говорят xinput
выходить корректно, когда это получает SIGINT
, Вы будете видеть file
больше не пусто (предположение, что это не отказывает, поскольку называющий библиотечные функции от обработчиков сигналов не гарантируется безопасным: рассмотрите то, что могло произойти, если сигнал входит, в то время как printf пишет в буфер).
Если это доступно, Вы могли бы использовать stdbuf
команда для изменения stdio
буферизация поведения:
stdbuf -oL xinput test 10 > file
Существует много вопросов на этом сайте, которые покрывают отключение stdio буферизация типа, где Вы найдете еще больше альтернативных решений.
Благодарен за то, что @rubo77 спрашивает это, это - большое осуществление. Для меня это было к ошибкам диапазона, какой английский язык является Жестким Материалом, к испорченному ритму: это получило забаву, быстро, даже при том, что сам алгоритм здесь довольно прост.
[заключительное редактирование: перемещенный в https://github.com/jthill/columnate/blob/master/columnate, ошибка, исправленная, главная строкой реализованный.]
Что-то близко к выводу ls
:
for i in *; do echo -en "${i}\t"; done; echo
Вы можете создать временную папку и создать пустые файлы для каждого строкового элемента вашего ввода без столбцов, а затем использовать ls
для столбцового вывода.
Пример:
mkdir -p /tmp/col
IFS=''
echo "something_very_long-something_very_long-something_very_long
output with space
space-at-beginning
3
4
5
6
7
8
9"|while read; do
touch /tmp/col/"$REPLY"
done
cd /tmp/col/
ls
rm /tmp/col/*
Выход:
3 7 something_very_long-something_very_long-something_very_long
4 8 ' space-at-beginning'
5 9
6 'output with space'
Здесь не используется минимальная ширина для каждой строки, как в решении @jthill выше, но также упоминается:
Я установил autogen
с помощью homebrew
, которая включает команду columns
, которая точно решает эту проблему:
brew install autogen
тест с
spit() { for i ; do echo "$i"; done; }
spit 1 2222222222222222 3 4 5 6 7777777777777777 8 $(seq 10 30) | columns
выход:
1 2222222222222222 3 4
5 6 7777777777777777 8
10 11 12 13
14 15 16 17
18 19 20 21
22 23 24 25
26 27 28 29
Примечание :возможно, пакета apt тоже достаточно:
apt install autogen
time ls | sort | columnate COLUMNS=$COLUMNS
– jthill 22.11.2013, 13:38