Я ненавижу себя за то, что говорю это, но
Есть больше чем один способ снять кожу с cat
.
Под этим я подразумеваю стандартный ввод, а затем стандартный ввод.
Или чтение с клавиатуры (терминала), а затем чтение с клавиатуры. Пытаться
less < afilename
Это работает так же, как
less afilename
Это означает, что less
должно иметь какой-либо способ чтения с клавиатуры, кроме чтения со стандартного ввода.
Вот еще одна команда, которая работает, даже если вы этого не ожидаете:
less afilename < /dev/null
Посмотрите на команду tty
.
Он сообщает имя tty (терминала), подключенного к стандартному входу.
Он работает, вызывая библиотечную функцию ttyname
с аргументом 0
(файловый дескриптор стандартного ввода).
less
вероятно , вызывая ttyname(1)
, чтобы получить имя TTY (терминал) , подключенный к стандартному выходу.
Затем он открывает этот tty для чтения и принимает от него команды.
Он не читает команды из стандартного ввода; это только для данных.
Итак, у нас есть два квазинезависимых процесса (cat
и less
), независимо (одновременно) считывающих с клавиатуры (т. Е. Tty / терминал) по двум независимым файловым дескрипторам.
Это запутанная ситуация, и это что-то вроде «состояния гонки».
Я нахожу это чем-то аналогичным действию автомата для игры в пинбол, в котором есть множество дорожек или дорожек, по которым может пройти мяч - и он всегда занимает одну ; это никогда не может занять больше, чем один. Точно так же, когда несколько процессов читают с одного и того же терминала одновременно, каждая набранная строка (если терминал находится в режиме строки) или каждый набранный символ (если терминал находится в режиме ввода символов) переходит ровно к одному процессу.
И выбор произвольный, мало чем отличающийся от действия пинбола.
Он не полностью «случайный», не более чем случайное планирование процессов; но это по сути непредсказуемо.
Итак, вот что происходит:
cat
читает со своего стандартного входа, который по умолчанию является терминалом, и записывает в свой стандартный вывод, который является каналом для less
.
- В какой-то момент,
less
вызывает ttyname(1)
, получает имя терминала, на котором он находится, и открывает его для чтения.
less
читает полный экран данных (т.е. 24 строки или что-то еще) со своего стандартного ввода (канал) и записывает их в стандартный вывод (терминал).
- Затем
less
выдает приглашение :
переводит терминал в символьный режим и начинает чтение с терминала (не со стандартного ввода).
- Итак, теперь у нас есть два процесса (
cat
и less
), считывающих данные с терминала одновременно, и включается феномен пинбола - символы (и / или строки), которые вы вводите, переходят либо к cat
либо к less
полуслучайному.
Если он переходит к cat
, он записывается в канал и less
воспринимает его как данные.
Если он идет less
оно интерпретируется как less
команды.
Это не имеет ничего общего с буферизацией.