Терминальные эмуляторы
Главная сторона заменяет линию (пару проводов TX / RX), которая идет к терминалу.
Терминал отображает символы, которые он получает на одном из проводов (некоторые из них являются управляющими символами и заставляют его выполнять такие действия, как перемещение курсора, изменение цвета ...), и отправляет на другом проводе символы, соответствующие клавишам, которые вы вводите.
Эмуляторы терминала, такие как xterm, ничем не отличаются, за исключением того, что вместо отправки и получения символов по проводам они читают и записывают символы в своем файловом дескрипторе на главную сторону. Как только они породили подчиненный терминал и запустили вашу оболочку, они больше не трогали это. В дополнение к эмуляции пары проводов, xterm может также изменить некоторые свойства дисциплины линии через этот файловый дескриптор на сторону мастера. Например, они могут обновить атрибуты размера, чтобы SIGWINCH отправлялся приложениям, которые взаимодействуют с ведомым pty, чтобы уведомить их об измененном размере.
Кроме этого, в эмуляторе терминала / терминала мало интеллекта .
То, что вы пишете на терминальное устройство (например, pty-slave), это то, что вы имеете в виду, чтобы отображаться там, то, что вы читаете с него, это то, что вы там набрали, так что эмулятору терминала не имеет смысла читать или писать на него. , Они на другом конце.
Дисциплина линии tty
Много интеллекта находится в с TTY дисциплины линии . Линейная дисциплина - это программный модуль (находящийся в драйвере, в ядре), помещенный поверх последовательного / pty-устройства, которое находится между этим устройством и линией / проводом (ведущей стороной для pty).
Последовательная линия может иметь терминал на другом конце, а также мышь или другой компьютер для работы в сети. Вы можете прикрепить дисциплину линии SLIP, например, чтобы получить сетевой интерфейс поверх последовательного устройства (или устройства pty), или у вас может быть дисциплина линии tty . Дисциплина линии tty является дисциплиной линии по умолчанию, по крайней мере, в Linux для последовательных и pty-устройств. В Linux вы можете изменить дисциплину строки с помощью ldattach
.
Вы можете увидеть эффект отключения дисциплины tty line с помощью команды stty raw -echo
(обратите внимание, что приглашение bash или другие интерактивные приложения, например, vi
устанавливают терминал в нужном им режиме, поэтому вы хотите использовать тупое приложение, подобное cat
этому). Затем все, что записано на ведомое оконечное устройство, сразу же отправляется на ведущую сторону для чтения xterm, и каждый символ, записанный xterm на ведущую сторону, сразу же доступен для чтения с ведомого устройства.
В дисциплине линии реализован редактор внутренней линии терминала . Например, с помощью stty icanon echo
(как по умолчанию), когда вы a
печатаете, xterm записывает a
в мастер, то дисциплина строки повторяет его обратно (делает a
доступным для чтения xterm
для отображения), но не делает ничего доступным для чтения на ведомой стороне. , Затем, если вы набираете backspace, xterm отправляет символ ^?
или ^H
, дисциплина строки (как таковая ^?
или ^H
соответствует erase
настройке дисциплины строки) отправляет обратно на мастер a ^H
, space
и ^H
для xterm
удаленияa
вы только что набрали на его экране и все еще ничего не отправляете в приложение, читающее со стороны ведомого устройства, оно просто обновляет свой внутренний буфер редактора строк, чтобы удалить то, что a
вы ввели ранее.
Затем, когда вы нажимаете Enter, xterm передает ^M
(CR), который дисциплина строки преобразует при вводе в ^ J (LF), и отправляет то, что вы ввели до сих пор, для чтения на ведомой стороне (приложение /dev/pts/x
, получающее чтение , получит то, что вы ввели, включая LF, но не тот, который a
вы удалили), в то время как на главной стороне он посылает CR и LF, чтобы переместить курсор на следующую строку и начало экрана.
Дисциплина линии также отвечает за отправку SIGINT
сигнала группе процессов терминала переднего плана, когда он получает ^C
символ на стороне мастера и т. Д.
Многие интерактивные терминальные приложения отключают большинство функций этой линейной дисциплины, чтобы реализовать их самостоятельно. Но в любом случае, имейте в виду, что терминал ( xterm
) не имеет к этому никакого отношения (кроме отображения того, что сказано для отображения).
И может быть только один сеанс на процесс и на оконечное устройство. К сеансу может быть подключен управляющий терминал, но это не обязательно (все сеансы начинаются без терминала, пока они не откроют один). xterm
в процессе, который он запрашивает для запуска вашей оболочки, обычно создается новый сеанс (и, следовательно, отсоединяется от терминала, с которого вы запустили, xterm
если есть), открывает новый, который /dev/pts/x
он породил, присоединяя это оконечное устройство к новому сеансу. Затем он выполнит вашу оболочку в этом процессе, поэтому ваша оболочка станет лидером сеанса. Ваша оболочка или любая интерактивная оболочка в этом сеансе, как правило, будет работать с группами процессов и tcsetpgrp()
для задания задних и фоновых заданий для этого терминала.
Что касается того, какая информация хранится на терминальном устройстве с дисциплиной tty (serial или pty) , это обычно то, что stty
команда отображает и изменяет. Все настройки дисциплины: размер экрана терминала, локальный, флаги ввода-вывода, настройки для специальных символов (например, ^ C, ^ Z ...), скорость ввода и вывода (не относится к ptys). Это соответствует функциям tcgetattr()
/, tcsetattr()
которые в Linux отображаются на TCGETS
/ TCSETS
ioctls, и TIOCGWINSZ
/ TIOCSWINSZ
для размера экрана. Вы можете утверждать, что текущая группа процессов переднего плана - это другая информация, хранящаяся в терминальном устройстве ( tcsetpgrp()
/ tcgetpgrp()
, TIOC{G,S}PGRP
ioctls), или текущий буфер ввода или вывода.
Обратите внимание, что информация о размере экрана, хранящаяся в терминальном устройстве, может не отражать реальность. Эмулятор терминала обычно устанавливает его (через тот же ioctl на основном размере), когда его окно изменяется, но он может выйти из синхронизации, если приложение вызывает ioctl на ведомой стороне или когда изменение размера не передается (в случае, если ssh-соединения, которое подразумевает создание другого pty, sshd
если ssh
игнорирует, SIGWINCH
например,). Некоторые терминалы также могут запрашивать свой размер с помощью escape-последовательностей, поэтому приложение может запрашивать его таким образом и обновлять дисциплину линии этой информацией.
Для получения более подробной информации вы можете, например, взглянуть на страницы man termios
и tty_ioctl
man в Debian.
Чтобы играть с другими дисциплинами линии:
Эмулируйте мышь псевдо-терминалом:
socat pty,link=mouse fifo:fifo
sudo inputattach -msc mouse # sets the MOUSE line discipline and specifies protocol
xinput list # see the new mouse there
exec 3<> fifo
printf '\207\12\0' >&3 # moves the cursor 10 pixels to the right
Выше главная сторона pty заканчивается socat на именованный канал ( fifo
). Мы подключаем эту fifo к процессу (оболочке), который записывает 0x87 0x0a 0x00, что в протоколе систем мыши означает no button pressed, delta(x,y) = (10,0)
. Здесь мы (оболочка) не эмулируем терминал, а мышь, 3 отправляемых нами байта не должны быть прочитаны (потенциально преобразованы) приложением из терминального устройства ( mouse
выше которого находится символическая ссылка, созданная socat
для некоторого /dev/pts/x
устройства) , но должны интерпретироваться как событие ввода мыши.
Создайте интерфейс SLIP:
# on hostA
socat tcp-listen:12345,reuseaddr pty,link=interface
# after connection from hostB:
sudo ldattach SLIP interface
ifconfig -a # see the new interface there
sudo ifconfig sl0 192.168.123.1/24
# on hostB
socat -v -x pty,link=interface tcp:hostA:12345
sudo ldattach SLIP interface
sudo ifconfig sl0 192.168.123.2/24
ping 192.168.123.1 # see the packets on socat output
Выше последовательный провод эмулируется socat
как сокет TCP между hostA и hostB. Дисциплина линии SLIP интерпретирует те байты, которыми обмениваются по этой виртуальной линии, как IP-пакеты, инкапсулированные SLIP, для доставки по sl0
интерфейсу.
cat /dev/ptmx &
которого открывается новый pty, но затем я не могу найти связанный с ним процесс, так как бы вы его использовали? Во-вторых, я пыталсяecho "1" >/dev/ptmx
, но это ничего не сделал ... Почему я заинтересован в этом? Часто, когда кто-то подключается удаленно черезssh
(например), вы получаетеPTY allocation request failed
илиNo controlling tty: open /dev/tty
ошибку, которая мешает управлению заданиями. Было бы неплохо лучше понять их.pty
страницу руководства для деталей.physical term
----tty
----bash
на терминалах иpty(m)
----tty
----pty(s)
----bash
на эмуляторах терминалов? Была лиtty
дисциплина ответственна за отображение персонажей на физическом терминале? 2. Это программа эмулятора терминала, которая подключается к клавиатуре / экрану для управления вводом? 3. Согласно тому, что я понял, вы сказали, что буферизация строки команд bash / всего ввода терминала выполняетсяtty
дисциплиной строки вместо буферов ввода / вывода функций CI / O. Это верно?Изменить: После этого ответа я написал специальную статью в своем блоге, для людей, которые будут заинтересованы в более подробной информации.
После долгих чтений я понял это.
/dev/ptmx
не выделяет подчиненную часть : она выделяет «главную часть псевдотерминала». / dev / ptmx не является главным псевдотерминалом : это главный мультиплексор псевдотерминала . Он был создан с использованием стандарта Unix98 PTY, чтобы избежать условий гонки при выделении главного псевдотерминала ( источника ).Основная часть (ptm) псевдотерминала не представлена в файловой системе. Он представлен дескриптором файла.
Ведомая часть (PTS) представлена в файл ,
/dev/pts/N
гдеN
этого число.КОЗ получается из PTM через последовательный вызов
grandpt
,unlockpt
,ptsname
. ( Источник )PTM заменяет драйвер AUR, предназначенный для связи с устройством, и линейную версию. Таким образом, он никоим образом не эмулирует терминал, но предоставляет возможность линейного редактирования и предоставляет способ визуализации и связи с очками. ( Источник )
Вот график того, что было TTY, подключенного к аппаратному устройству
А вот график tty, связанный с PTM
Файл ptm обрабатывает другие аргументы Ioctl (ISPTM, UNLKPT, TIOCREMOTE, TIOCSIGNAL), чем pts.
Процессы взаимодействуют с устройствами посредством действий, выполняемых с виртуальным файлом (чтение, запись, ioctl ...). Сам файл не существует, и драйвер использует файл для запуска действий при вызове методов чтения или записи. (См. Приложение для информации о водителях)
TTY определяет точный способ взаимодействия с ним. Процессы пишут и читают с устройства и ожидают одинакового поведения независимо от того, какой тип TTY реализован.
Очки ведут себя как TTY-драйвер. Его метод чтения и записи используется для реализации поведения драйвера TTY. Поскольку реального устройства для отправки данных не существует, создается пара потоков, и ptm реализует функцию чтения для чтения данных, отправляемых pts в поток, и функцию записи для отправки данных в поток, который будет доступен когда оч его прочтет.
Помните, что файл, представляющий устройство, не является классическим файлом, и если он
xterm
хочет увидеть, что было записано в файл, он не может просто вызвать его открыть и прочитать, так как эти функции имеют совершенно другое поведение.Я так не думаю, идентификатор сессии определяется первым процессом, который присоединяет pts (обычно bash), и я не вижу способа создать другой сеанс и прикрепить его к тем же pts. Может быть, такой инструмент
socat
может сделать это?Pts хранит 2 категории информации о терминале, с которым он связывается: the
Terminfo
и theTermcap
. Обычно многие эмуляторы терминалов основаны на библиотеке, которая управляет для них информацией termcap (которая предоставит все значения возможностей, например, для эмуляции VTX100). Примером такой библиотеки является libvte . Редактировать (см. Комментарий Stephane Chazelas): возможности терминала не сохраняются очками.пристройка
источник
Вот схема, которую я сделал некоторое время назад о том, как
sshd
работает. Это не касается работы линейной дисциплины и прочего, но добавляет реальную иллюстрацию того, кто с чем взаимодействует:источник
-T
, который, по словам человека, отключает выделение псевдотерминала. Например:ssh -T emasculateur@localhost "sleep 10"
затемps aux|grep sleep
показывает это:emasculateur 21826 0.0 0.0 23032 3728 ? Ss 02:49 0:00 zsh -c sleep 10
В этом случае, где bash пишетstdout
иstderr
? Я надеюсь, что мой вопрос имеет смысл./dev/null
нравится обычному демону, но не уверен. Смотрите также: serverfault.com/questions/593399/…nohup
илиscreen
/tmux
.man pts
говорит:О себе
/dev/pts/X indexing
:каждый X это сеанс, который вы открываете, поэтому рабам нужно индексировать.
О
TeteType (/dev/ttyN
)Это настоящая консоль была сгенерирована вашей загрузочной системой, такой как
sysV
.О том, почему рабский хозяин заменил мастера: http://commons.wikimedia.org/wiki/File:Termios-script-diagram.png
источник