lessчитает данные для отображения из stdin и читает команды из tty. Это разные вещи.
Уильям Перселл
2
@WilliamPursell Да, я знаю. Но есть только один стандартный поток ввода, верно?
iBug
4
Да, есть один входной поток и один tty. lessчитает данные из stdin и команды из tty.
Уильям Перселл
Ответы:
52
Как упомянул Уильям Перселл , lessсчитывает нажатия клавиш пользователя из терминала. Он явно открывает /dev/ttyуправляющий терминал; это дает ему дескриптор файла, отдельный от стандартного ввода, из которого он может читать интерактивный ввод пользователя. При необходимости он может одновременно считывать данные со стандартного ввода. (Это может также написать напрямую в терминал при необходимости.)
Вы можете увидеть это, запустив
some_command | strace -o less.trace -e open,read,write less
Перемещайтесь по входу, выходите lessи смотрите на содержимое less.trace: вы увидите, что оно открыто /dev/tty, и прочитаете как из файлового дескриптора 0, так и из того, который был возвращен при его открытии /dev/tty(вероятно, 3).
Это обычная практика для программ, желающих убедиться, что они читают и пишут в терминал. Одним из примеров является SSH, например, когда он запрашивает пароль или фразу-пароль.
Как пояснил на Шили , если /dev/ttyне может быть открыт, lessбудет считываться из стандартной ошибки (дескриптор файла 2). lessИспользование /dev/ttyбыло введено в версии 177, выпущенной 2 апреля 1991 года.
При попытке запуска cat /dev/tty | less, как и предложил на Хаген фон Eitzen , lessпреуспеет в открытии , /dev/ttyно не получите никакой информации от него до тех пор , catзакрывает его. Таким образом, вы увидите пустой экран, и ничего больше, пока не нажмете, CtrlCчтобы убить cat(или убить его каким-либо другим способом); затем lessпокажет все, что вы ввели во время catработы, и позволит вам контролировать это.
@ Grawity Я думаю, что Эндрю говорит о том, что cat blah |его можно заменить < blah, и даже в этом случае это не нужно, так как less blahработает тоже (хорошо less -f /dev/tty). Но чтение из /dev/ttyэто немного особого случая, и все три варианта ( cat /dev/tty | less, less < /dev/ttyи less -f /dev/tty) дают разные результаты.
Стивен Китт
1
Всегда ли / dev / tty указывает на правильное место? Я думаю, вам обычно нужно использовать / dev / ptsX?
StarWeaver
2
@ StarWeaver увидеть этот вопрос о разнице между /dev/ttyи /dev/pts/....
Стивен Китт
26
UNIX предоставляет два метода для чтения пользовательского ввода при перенаправлении стандартного ввода:
Оригинальный метод заключается в чтении из stderr . Stderr открыт для записи и чтения, и это все еще упоминается в POSIX.
В более поздних версиях UNIX (около 1979 г.) был добавлен /dev/ttyинтерфейс драйвера, который позволяет открывать управляющий tty процесса. Поскольку существуют процессы без управляющего tty, возможно, что попытка открытия /dev/ttyне удалась. Поэтому дружественно написанное программное обеспечение имеет запасной вариант к исходному методу, а затем пытается прочитать из stderr.
Является ли причиной того, что stderr используется для чтения, потому что он реже всего перенаправляется? Я не вижу никакой другой разницы между ним и stdout (или для этого mater stdin, до перенаправления).
Ctrl-Alt-Delor
4
Да, это потому, что это дескриптор файла, у которого меньше всего шансов быть перенаправленным.
щили
@ ctrl-alt-delor: типично, что оболочки работают с stdin, stdout и stderr, dup()хотя все они являются лицензиями одного и того же описания файла, но все они открыты на tty. ( По- видимому POSIX все еще требует или предложить (этот ответ не говорит) , что STDERR быть для чтения / записи FD, не открыл что - то вроде open("/dev/ttyS0", O_WRONLY)чтения STDERR потерпит неудачу в этом случае.)
less
читает данные для отображения из stdin и читает команды из tty. Это разные вещи.less
читает данные из stdin и команды из tty.Ответы:
Как упомянул Уильям Перселл ,
less
считывает нажатия клавиш пользователя из терминала. Он явно открывает/dev/tty
управляющий терминал; это дает ему дескриптор файла, отдельный от стандартного ввода, из которого он может читать интерактивный ввод пользователя. При необходимости он может одновременно считывать данные со стандартного ввода. (Это может также написать напрямую в терминал при необходимости.)Вы можете увидеть это, запустив
Перемещайтесь по входу, выходите
less
и смотрите на содержимоеless.trace
: вы увидите, что оно открыто/dev/tty
, и прочитаете как из файлового дескриптора 0, так и из того, который был возвращен при его открытии/dev/tty
(вероятно, 3).Это обычная практика для программ, желающих убедиться, что они читают и пишут в терминал. Одним из примеров является SSH, например, когда он запрашивает пароль или фразу-пароль.
Как пояснил на Шили , если
/dev/tty
не может быть открыт,less
будет считываться из стандартной ошибки (дескриптор файла 2).less
Использование/dev/tty
было введено в версии 177, выпущенной 2 апреля 1991 года.При попытке запуска
cat /dev/tty | less
, как и предложил на Хаген фон Eitzen ,less
преуспеет в открытии ,/dev/tty
но не получите никакой информации от него до тех пор ,cat
закрывает его. Таким образом, вы увидите пустой экран, и ничего больше, пока не нажмете, CtrlCчтобы убитьcat
(или убить его каким-либо другим способом); затемless
покажет все, что вы ввели во времяcat
работы, и позволит вам контролировать это.источник
cat blah |
его можно заменить< blah
, и даже в этом случае это не нужно, так какless blah
работает тоже (хорошоless -f /dev/tty
). Но чтение из/dev/tty
это немного особого случая, и все три варианта (cat /dev/tty | less
,less < /dev/tty
иless -f /dev/tty
) дают разные результаты./dev/tty
и/dev/pts/...
.UNIX предоставляет два метода для чтения пользовательского ввода при перенаправлении стандартного ввода:
Оригинальный метод заключается в чтении из stderr . Stderr открыт для записи и чтения, и это все еще упоминается в POSIX.
В более поздних версиях UNIX (около 1979 г.) был добавлен
/dev/tty
интерфейс драйвера, который позволяет открывать управляющий tty процесса. Поскольку существуют процессы без управляющего tty, возможно, что попытка открытия/dev/tty
не удалась. Поэтому дружественно написанное программное обеспечение имеет запасной вариант к исходному методу, а затем пытается прочитать из stderr.источник
dup()
хотя все они являются лицензиями одного и того же описания файла, но все они открыты на tty. ( По- видимому POSIX все еще требует или предложить (этот ответ не говорит) , что STDERR быть для чтения / записи FD, не открыл что - то вродеopen("/dev/ttyS0", O_WRONLY)
чтения STDERR потерпит неудачу в этом случае.)