Меньше получает клавиатурный ввод от stderr?
Я смотрю на код утилиты 'less', особенно на то, как он получает ввод с клавиатуры. Интересно, что в строке 80 файла ttyin.c он устанавливает дескриптор файла для чтения из:
/*
* Try /dev/tty.
* If that doesn't work, use file descriptor 2,
* which in Unix is usually attached to the screen,
* but also usually lets you read from the keyboard.
*/
#if OS2
/* The __open() system call translates "/dev/tty" to "con". */
tty = __open("/dev/tty", OPEN_READ);
#else
tty = open("/dev/tty", OPEN_READ);
#endif
if (tty < 0)
tty = 2;
Разве файловый дескриптор 2 не является stderr? Если так, то WTH?! Я думал, что ввод с клавиатуры был отправлен через стандартный ввод.
Интересно, даже если вы делаете ls -l * | less
После завершения загрузки файла вы все равно можете использовать клавиатуру для прокрутки вверх и вниз, но если вы это сделаете ls -l * | vi
, тогда vi будет кричать на тебя, потому что он не читает с stdin. Что за большая идея? Как я оказался в этой странной новой стране, где stderr - это способ сообщать об ошибках на экран и читать с клавиатуры? Я не думаю, что я в Канзасе больше...
4 ответа
$ ls -l /dev/fd/ lrwx------ 1 me me 64 2009-09-17 16:52 0 -> /dev/pts/4 lrwx------ 1 me me 64 2009-09-17 16:52 1 -> /dev/pts/4 lrwx------ 1 me me 64 2009-09-17 16:52 2 -> /dev/pts/4
При входе в систему на интерактивном терминале все три стандартных файловых дескриптора указывают на одно и то же: ваш TTY (или псевдо-TTY).
$ ls -fl / dev / std {in, out, err} lrwxrwxrwx 1 root root 4 2009-09-13 01:57 / dev / stdin -> fd / 0 lrwxrwxrwx 1 root root 4 2009-09-13 01:57 / dev / stdout -> fd / 1 lrwxrwxrwx 1 root root 4 2009-09-13 01:57 / dev / stderr -> fd / 2
По договоренности мы читаем из 0
и написать 1
а также 2
, Однако ничто не мешает нам поступить иначе.
Когда ваша оболочка работает ls -l * | less
, это создает трубу из ls
дескриптор файла 1
в less
дескриптор файла 0
, Очевидно, что less
больше не может читать ввод с клавиатуры пользователя из файлового дескриптора 0
- он пытается вернуть TTY как может.
Если less
не был отсоединен от терминала, open("/dev/tty")
даст это TTY.
Тем не менее, если это не удается... что вы можете сделать? less
делает последнюю попытку получить TTY, предполагая, что дескриптор файла 2
привязан к тому же, что и дескриптор файла 0
будет привязан к, если бы он не был перенаправлен.
Это не отказоустойчиво:
$ ls -l * | setsid less 2> / dev / null
Вот, less
назначается собственный сеанс (поэтому он больше не является частью активной группы процессов терминала, вызывая open("/dev/tty")
потерпеть неудачу), и его файловый дескриптор 2
был изменен - сейчас less
выходит немедленно, потому что он выводит на TTY, но не получает никакого пользовательского ввода.
Ну... во-первых, вы, кажется, пропустили open()
вызов, который открывает '/dev/tty'. Он использует файловый дескриптор 2 только в случае сбоя вызова open(). В стандартной системе Linux и, вероятно, во многих Unix-файлах существует / dev / tty, и он вряд ли вызовет сбой.
Во-вторых, комментарий вверху дает ограниченное количество объяснений, почему они возвращаются к файловому дескриптору 2. Я предполагаю, что stdin
, stdout
, а также stderr
в любом случае, в значительной степени связаны с /dev/tty/, если не перенаправлены. И так как наиболее распространенные перенаправления для для стандартного ввода и / или стандартного вывода (через трубопровод или <
/ >
), но реже для stderr
шансы на то, что с помощью stderr
Скорее всего, все еще будет подключен к "клавиатуре".
Тот же вопрос с ответом, в конечном счете, от человека, который его задал, находится на linuxquestions, хотя они цитируют немного другой источник из less
, И нет, я не понимаю большинство из них, поэтому я не могу помочь в этом:)
Похоже, это специфическая функциональность Linux, которая отправляет ввод с клавиатуры на FD 2.