Существует также OLDPWD
, переменная среды, которая, согласно IEEE 1003.1 (POSIX), должен быть обновлен с предыдущим рабочим каталогом каждый раз cd
изменяет рабочий каталог (для любопытных, строка 80244 из страницы 2506 IEEE 1003.1-2008).
Это просто, что, когда 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 буферизация типа, где Вы найдете еще больше альтернативных решений.
Команда может непосредственно записать в /dev/tty
предотвращение регулярного перенаправления для случая.
$ cat demo
#!/bin/ksh
LC_ALL=C TZ=Z date > /dev/tty
$ ./demo >demo.out 2>demo.err
Fri Dec 28 10:31:57 2012
$ ls -l demo*
-rwxr-xr-x 1 jlliagre jlliagre 41 2012-12-28 11:31 demo
-rw-r--r-- 1 jlliagre jlliagre 0 2012-12-28 11:31 demo.err
-rw-r--r-- 1 jlliagre jlliagre 0 2012-12-28 11:31 demo.out
/dev/tty
в системе Linux использовать script -c ./demo demo.log
(от util-linux
).
– ndim
28.12.2012, 19:40
Это похоже xinput
вывод отклонений в файл, но не отклоняет вывод к терминалу. Достигнуть этого, вероятно xinput
используйте системный вызов
int isatty(int fd)
проверять, относится ли filedescriptor, который будет открыт, к терминалу или нет.
Я наткнулся на то же явление только что с названной программой dpic
. После того, как я изучил источник и некоторую отладку, я удалил строки, связанные с isatty
и все работало как ожидалось снова.
Но я соглашаюсь с Вами, что этот опыт является очень тревожащим ;)
isatty
тестирование сделано. ouput сгенерирован printf
функция (я думаю, что это - стандарт C), один. Я добавил некоторых fprintf(stderr,"output")
и это возможно перенаправить +, доказывает, что целый код действительно runned в случае xinput. Спасибо за предложение, в конце концов, это был первый след здесь.
– humanityANDpeace
28.12.2012, 13:11
Да. Я даже сделал это во времена DOS, когда я запрограммировал в Паскале. Я предполагаю, что принцип все еще содержит:
Это действительно повреждало любые каналы.
con
название DOS того, что называет Unix /dev/tty
, т.е. (управление) терминал.
– Gilles 'SO- stop being evil'
30.12.2012, 00:15
В Вашем test.c
файл Вы могли сбросить буферизированное использование данных (void)fflush(stdout);
непосредственно после Вашего printf
операторы.
// in test.c
printf("key %s %d ", (Event.type == key_release_type) ? "release" : "press ", key->keycode);
//fprintf(stderr,"key %s %d ", (Event.type == key_release_type) ? "release" : "press ", key->keycode);
//(void)fflush(NULL);
(void)fflush(stdout);
На командной строке можно включить вывод с буфером строки путем выполнения xinput test 10
в псевдотерминале (имущество) с script
команда.
script -q /dev/null xinput test 10 > file # FreeBSD, Mac OS X
script -c "xinput test 10" /dev/null > file # Linux
setvbuf(stdout, (char *) NULL, _IONBF, NULL)
. Возможно, это также представляет интерес!? – user1146332 28.12.2012, 14:18stdbuf -o0
делает, в то время какstdbug -oL
строка восстановлений, буферизующая как то, когда вывод переходит к терминалу.stdbuf
действительно вынуждает приложение звонитьsetvbuf
использование aLD_PRELOAD
прием. – Stéphane Chazelas 28.12.2012, 14:23unbuffer test 10 > file
(unbuffer
частьexpect
инструменты) – Olivier Dulac 28.12.2012, 17:40