Как стать автором
Обновить

Комментарии 44

Много букв, не осилил ( Но за труды спасибо )
Это я еще тут многое пропустил) Но на самом деле, если разобраться, нет совершенно ничего сложного :)
Так то да, но лично я бы эту статью разбил на 2 части для более простого восприятия )
Было интересно! Спасибо!
Понравилось про вывод из одного терминала на другой
НЛО прилетело и опубликовало эту надпись здесь

Про интересные реализации вряд ли скажу, пользуюсь обычным Gnome и не жалуюсь. А что вы имеете в виду под терминалом для телеграм бота? Эмулятор терминала — это графическая программа для возможности запуска терминалов внутри оконного интерфейса, так что не очень понимаю как тут связаны бот и терминал :) Возможно, вы хотите производить процессинг ввода и имеете в виду общение с ботом прямо в терминале, а не из отдельного графического приложения (то есть просто stdin/stdout)? Тогда ответ да — в этом вам помогут псевдотерминалы. Так, например, поступают ssh и screen.

НЛО прилетело и опубликовало эту надпись здесь

Итак, вы запустили терминал и в нем работает Bash. Вы хотите из Bash запустить бота и общаться с ним? Извините, до сих пор не понимаю какова ваша цель)

НЛО прилетело и опубликовало эту надпись здесь

Понял вас) Да, так можно. Например, для gnome-terminal: gnome-terminal -e 'telegram-bot'. Просто передавайте параметром любую программу, которую необходимо запустить при создании процесса нового терминала. Думайте об этом параметре как о аргументе, передающемся в Си вызов exec().

Но вы всегда можете написать свой эмулятор терминала, который будет запускать только ваш бот :)

А это Terminal:
<фото>


А в правом-нижнем углу фото — это год? ;-)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
А теперь нужна третья часть про «Далее GNOME Terminal Server передает строку в X Server, который отобразит её на дисплей». Если уж лезть в эту нору, то до самого ̶к̶р̶о̶л̶и̶к̶а̶ железа!

Все может быть ;)

является каламбуром для «Born again» Shell, то есть «возрождённый» Shell

Здесь надо уточнить, что оригинальная оболочка sh называется еще "оболочкой Борна" (в честь ее автора — Стивена Борна). Соответственно bash — это Bourne again shell, в этом и каламбур. Без контекста не очень понятно (конечно, не для тех, кто уже знает).

Спасибо, действительно стоит уточнить.

Шикарно! Сам хотел что-то подобное написать, но работа съела все время :(
НЛО прилетело и опубликовало эту надпись здесь

Рад стараться! А можно ссылку на ту статью? Мне бы и самому было бы интересно почитать про терминалы в винде

Это всё очень круто, но когда и кому (задача/специальность), это может понадобиться постоянно держать в голове?
Некоторые основы нужны каждому, кто работает в терминале, чтобы понять, например, что происходит, если нештатный выход из полноэкранной программы привёл обстановку в нерабочее состояние.
Вот оставила она в raw-режиме, теперь как из него вернуться в нормальный? Предположим, что закрывать окно (если окно) — нельзя. Надо отдать команду (reset или stty sane), но сделать это не получается — нас не слышат, потому что icrnl выключено. Надо жать в этом случае не reset, а reset<Ctrl+J>. Потому что клавиша Enter генерирует не Ctrl+J (LF, код 10), а Ctrl+M (CR, код 13), и только уже в модуле дисциплины присутствие icrnl переводит его в тот код, что ожидает обычный ввод строки. «И сырость капает на клавишу ВК».

У сетевых админов маршрутизаторы ряда классических производителей типа Cisco, Juniper управляются, по крайней мере при начальном конфигурировании, через последовательный порт. Тоже надо понимать хотя бы основы, что оно такое и как может работать.

У эмбедщиков или у тех админов, что управляют машинками по IPMI, очень типичный вариант — serial console поверх IPMI, которую нужно ещё уметь настраивать и понимать её глюки (и там проблемы сильно выше описанной — я у, кажется, Dell видел реализацию, у которой внутри конвертировались даже не битовые потоки, а эмуляции напряжения на порту, между разными скоростями).

Или вот ещё — на моей прошлой работе была одна жутко специализированная и дорогущая проприетарная программа, которая работала по капризу автора как терминальная (были и другие варианты доступа, но считались не основными). Предполагалось, что ею будет управлять человек непосредственно с терминала, некоторые вещи можно было делать только через него. А надо было автоматизировать управление (запуск/останов, отдачу команд). Пришлось запускать под screenʼом через самопальный переходник, что запускал целевую программу под отдельным PTY, гонял данные туда-обратно, настраивал штатную дисциплину, слушал команды по управлению, мог вставлять от имени пользователя какие-то последовательности символов или рассказывать, что последнее она вывела…

Действительно глубокое погружение.
И на удивление качественно подготовленный материал, хороший стиль, в сравнении с большинством современных публикаций на Хабре.
Автор, пиши ещё!

Хорошее изложение, мне понравилось.

Кроме беды с этим термином:
TTY Line Discipline (рус. — дисциплина линии)

«Дисциплина линии» — на редкость неудачный перевод для «line discipline».

Да, я в курсе, что именно такая калька применяется повсеместно. Но, к сожалению, она затрудняет понимание на русском языке.
Из-за такого перевода line discipline постоянно ассоциируют с линией связи терминала (т.к. tty действительно подразумевает наличие таковой), но никакого отношения ни к каким линиям line discipline не имеет.
Английское «line» в этом контексте на русский переводится исключительно как «строка», т.к. подразумевает последовательность символов до символа LF («line feed» — «перевод строки»).

Почему-то нигде переводчикам не приходит в голову называть строки линиями — ни в текстовых редакторах, ни в табличных процессорах, ни в тех же эмуляторах терминалов.
Поэтому «line discipline» — это строковый буфер, строковая политика, обработчик строки, на худой конец — дисциплина строки, но никак не дисциплина линии.
Из-за такого перевода line discipline постоянно ассоциируют с линией связи терминала (т.к. tty действительно подразумевает наличие таковой), но никакого отношения ни к каким линиям line discipline не имеет.

Да, объяснение про строку и правда звучит логично, но разве не по этой самой линии связи передавался ввод? Тогда и название было бы вполне оправдано.

но разве не по этой самой линии связи передавался ввод?

line discipline находится между приложением и драйвером терминала.

Ее задача — обеспечение построчного ввода/вывода (т.е. в первую очередь — задачи буферизации) с возможностью обработки метаинформации (в виде служебных символом в том же потоке). Для пользователей это, в частности, позволяет редактировать набираемую команду.

А «эта самая линия» находится «за» драйвером и в общем случае ее может вообще не быть — может быть ее эмуляция, до чего line discipline нет абсолютно никакого дела. Аналогом «этой самой линии» для псевдотерминала является связь PTS<-->PTM.

Да, в конкретных имплементациях обрабатываемая метаинформация может включать в том числе управление «той самой линией» и тогде некоторые служебные символы могут транслироваться, например, в ioctl драйвера, но обычно задачи line discipline сводятся к простому форматированию текста.

Замечу одну неточность в вашем ответе:


Вы сказали, что связь между pty master и pty slave это аналог линии связи. Однако, ведь это не правда. Линия связи лежала перед UART устройством. Байты с UART устройства принимал UART драйвер и передавал их после обработки драйверу консоли. Сейчас заместо uart драйвера и драйвера консоли выступают PTM и PTS устройства. Дисциплина линии же все также лежит между этими двумя устройствами, но здесь нет никакой линии связи больше. Конечно, это не отдельная дисциплина линии, а экспортируется дисциплина одного из устройств. Линия связи ушла, но дисциплина линии осталась. Точно также, как и название TTY — очень много концепций сохранилось с тех времен, поэтому не забывайте, что, может быть, хоть и сейчас "дисциплина линии" это что-то непонятное, но если мы окунемся в прошлое, то название будет иметь смысл.

> Ее задача — обеспечение построчного ввода/вывода (т.е. в первую очередь — задачи буферизации)

Это задача одного конкретного варианта дисциплины — которая называется «нормальной» или тоже «терминальной». В Linux это константа N_TTY среди констант вариантов дисциплины.

Могут быть выбраны другие line discipline. Вот отдельная программа установки дисциплины на TTY — заметьте, сколько разных дисциплин она знает, и все кроме одной — никаких «строк» не знают, в основном это сетевые стеки с пакетами. На программном уровне это ставится через TIOCSETD.
> Поэтому «line discipline» — это строковый буфер, строковая политика, обработчик строки, на худой конец — дисциплина строки, но никак не дисциплина линии.

Нет, именно линии. Потому что такие дисциплины бывают:
  • обычная терминальная — только тогда «строка» имеет хоть какое-то смысл в обработке;
  • SLIP или PPP — тогда никаких строк нет, работа на уровне байтов; задача дисциплины — вылавливать пакеты, отправлять их в IP стек, в случае PPP — также отрабатывать управляющие пакеты протокола (или хотя бы передавать их в управляющий процесс);
  • изредка — другие (вот большой список), в которых тоже нет строк.
Нет, именно линии.

Да, похоже вы правы.

Мне не приходилось работать с сетью через терминал.
И я всегда считал, что в этом случае, как часто бывает, существующий механизм line discipline был расширен на несвойственные ему изначально задачи.
Но вот предполагалась ли изначально, что дисциплина будет работать с бинарными пакетами, сейчас сказать не так просто — все это было в pre-git истории.
> Мне не приходилось работать с сетью через терминал.

Ясно. Мне приходилось с обеих сторон — строить доступ по PPP и SLIP по модемному дозвону.

> Но вот предполагалась ли изначально, что дисциплина будет работать с бинарными пакетами, сейчас сказать не так просто — все это было в pre-git истории.

«Pre-git» история немного доступна. В Lionsʼ Book (подробная структура Bell Unix V6) описаны функции процессинга ввода-вывода как для терминала, но хардкодом, а не выбираемым модулем.
Расширение на сменные модули (с обычным терминальным процессингом как умолчательным) появилось, скорее всего, в 4.2BSD-4.3BSD, со введением dial-up и связей по постоянным линиям поверх последовательных портов. Но тут самая тёмная часть истории из-за закрытости исходников; 4.4BSD-Lite-based BSD системы — открытые — уже содержали line discipline как устоявшееся и почти идентичным кодом, что нас приводит таки во времена не позже общей 4.4.
Реквестирую комментарий Иртегова.
Очень уж он любит вопрос «что такое терминал?».
В терминале запускается нужная программа с помощью вызова функции exec(). Обычно запускается какой-то Shell (например, Bash).
Разрешите наивный вопрос. Разве exec не подразумевает замену вызывающей программы на вызываемую? И получается, что Shell у нас должен появиться вместо эмулятора терминала. Проясните, пожалуйста, этот момент.

Да, конечно же спавнится новый процесс и уже в нем запускается Shell. Смотрите эту функцию: https://developer.gnome.org/vte/unstable/VteTerminal.html#vte-terminal-spawn-async. Это — VTE widget, созданный и поддерживаемый GNOME. В нем и происходит почти вся работа по созданию терминалов. Конкретно в данной функции 4 аргументом принимается нужная команда, создается PTY и в новом процессе запускается данная команда на созданном PTY.

Статья у вас фундаментальная. И по её изучении я в том числе нарисовал схему (некий сухой остаток для закрепления). Если не сложно, посмотрите, что нужно в ней подправить.
Заголовок спойлера

Посмотрел.


  1. /dev/ptmx — это все таки устройство. Фраза — "это не устройство, а интерфейс" странная, так как данное и является интерфейсом для создания pty. Как это работает? Мы вызываем open(/dev/ptmx), и вызов open обслуживает драйвер данного устройства, конкретнее мы видели, что за это отвечает функция ptmx_open.
  2. "PTM и PTS — это виртуальные устройства...". Да, это верно, но не по той причине что вы написали, а потому, что они не существуют физически на диске, а живут в виртуальной файловой системе /dev, т.е. живут в памяти, в ядре. Вообще, то, как я определил виртуальные устройства — расходится с тем, что говорит википедия. Там виртуальные устройства — это устройства, не взаимодействующие напрямую с аппаратными устройствами. Так что лучше избегать понятия "виртуальное устройство" по отношению к ptm/pts и говорить, что PTM и PTS являются файлами устройств, а конкретнее, терминальными устройствами. Не думаю, что их можно назвать виртуальными устройствами, так как формально они взаимодействуют с терминалом. Вот /dev/null уже является виртуальным устройством.
  3. Ну и последнее я считаю своей самой большой ошибкой в статье. Зря я вообще заикнулся о gnome терминале. Дело в том, что его работа намного сложнее, чем какой-нибудь xterm. Он не создает новые процессы для терминалов, а запускает их внутри тредов. Программы внутри терминала конечно же запускаются в отдельных процессах (а конкретнее этим занимается vte widget и его функция vte_terminal_spawn_async). Мой вам совет — поизучайте xterm — крайне простой и понятный эмулятор терминала, который, более того, работает в обход gtk, gnome и всяких других графических тулкитов.
    Если вам интересно, убедиться в том, что gnome терминал — не отдельный процесс, можно достаточно просто. Введите:
    $ ps --pid $$ --format ppid=

И вы увидите, что родителем баша является сам Gnome Terminal Server. Да, это кажется странным со стороны, но наверняка на то были причины, что gnome терминалы работают внутри тредов. Первую причину, которую я вижу, это функциональность вкладок (tabs).


Пишите в лс, можем еще что-то обсудить, если понятнее не стало :)

Хотя насчет простоты xterm я все таки погорячился — его соурс код сложно понятен, да и вообще сам он раздут сильно по возможностям и наполнен многими ненужными в актуальное время вещами. Но в качестве понимания того, как примерно эмулятор терминала работает, вполне пойдет

Рекомендую st для более глубого изучения устройства терминалов — это точно самый простой и понятной терминал на сегодня. https://st.suckless.org/

Могут. Но за пределами конкретных существующих контекстов (в каких-то новых).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории