Snažím se přijít na to, jak funguje tty (pracovní postup a odpovědnosti jednotlivých prvků). Četl jsem o tom několik zajímavých článků, ale stále jsou tam některé rozmazané oblasti.
To je to, co jsem zatím pochopil:
- Emulace terminálu provádí různá systémová volání
/dev/ptmx
, hlavní část pseudoterminálu. - Hlavní část pseudoterminálu přiděluje soubor v
/dev/pts/[0-N]
, odpovídající zastaralému sériovému portu, a „připojí“ k němu podřízený pseudoterminál. - Podřízený pseudoterminál uchovává informace, jako je ID relace, úloha v popředí, velikost obrazovky.
Zde jsou mé otázky:
- Má ptmx nějaký účel kromě přidělení otrokářské části? Poskytuje nějaký druh „inteligence“ , nebo emulovaný terminál
(například xterm) má veškerou inteligenci chovat se jako
terminál? - Proč xterm musí interagovat s hlavní částí, protože předává pouze stdout a stdin podřízené části? Proč nemůže
přímo zapisovat a číst ze souboru pts ? - Je ID relace vždy připojeno k jednomu souboru pts a naopak?
Mohl bych zadat příkaz ps a najít 2 sessionId pro stejný
/dev/pts/X ? - Jaké další informace obsahuje
body
ukládat? Aktualizuje Xterm všechna
pole sám, neboptm
přidat k tomu nějakou „inteligenci“?
Přijatá odpověď:
Emulátory terminálu
Hlavní strana nahrazuje linku (pár vodičů TX/RX), která vede k terminálu.
Terminál zobrazí znaky, které přijímá na jednom z drátů (některé z nich jsou řídicí znaky a umožňují mu dělat věci, jako je pohyb kurzoru, změna barvy…) a na jiném drátu odesílá znaky odpovídající klávesám, které píšete.
Emulátory terminálu jako xterm se neliší až na to, že místo odesílání a přijímání znaků po drátech čtou a zapisují znaky na svém deskriptoru souboru na hlavní stranu. Jakmile vytvoří terminál otroků a spustí na něm váš shell, už se toho nedotknou. Kromě emulace dvojice vodičů může xterm také změnit některé vlastnosti disciplíny linky prostřednictvím tohoto deskriptoru souboru na hlavní stranu. Mohou například aktualizovat atributy velikosti tak, aby byl aplikacím, které komunikují s podřízeným pty, odeslán SIGWINCH, aby je informoval o změně velikosti.
Kromě toho je zde málo inteligence v emulátoru terminálu/terminálu.
To, co zapisujete do terminálového zařízení (jako je pty slave), je to, co chcete, aby se tam zobrazovalo, to, co z něj čtete, je to, co jste tam napsali, takže nemá smysl, aby to emulátor terminálu četl nebo zapisoval . Oni jsou ti na druhém konci.
Disciplína tty line
Hodně inteligence je v disciplině tty line . Disciplína linky je softwarový modul (umístěný v ovladači, v jádře) nasunutý na zařízení sériového/pty, které je umístěno mezi tímto zařízením a linkou/drátem (hlavní strana pro pty).
Sériová linka může mít na druhém konci terminál, ale také myš nebo jiný počítač pro síťování. Můžete připojit disciplínu SLIP line, například abyste získali síťové rozhraní na sériové zařízení (nebo zařízení pty), nebo můžete mít tty liniová disciplína. Disciplína tty line je výchozí disciplína line alespoň na Linuxu pro sériová zařízení a zařízení pty. V Linuxu můžete změnit disciplínu řádku pomocí ldattach
.
Účinek deaktivace disciplíny tty line můžete vidět zadáním stty raw -echo
(všimněte si, že výzva bash nebo jiné interaktivní aplikace jako vi
nastavte terminál v přesném režimu, který potřebují, takže chcete použít hloupou aplikaci jako cat
vše, co je zapsáno do podřízeného koncového zařízení, se okamžitě dostane na hlavní stranu, kde je xterm přečten, a každý znak zapsaný xtermem na hlavní stranu je okamžitě k dispozici pro čtení z slave zařízení.
Disciplína linky je kde interní editor linky koncového zařízení je implementován. Například pomocí stty icanon echo
(jako výchozí nastavení), když napíšete a
, xterm zapíše a
na mistra, pak se čárová disciplína ozývá to zpět (vytváří a
k dispozici pro čtení pomocí xterm
pro zobrazení), ale nezpřístupňuje nic pro čtení na podřízené straně. Pokud pak zadáte backspace, xterm odešle ^?
nebo ^H
znak, řádková disciplína (jako ten ^?
nebo ^H
odpovídá erase
nastavení disciplíny linky) odešle zpět na master ^H
, mezera
a ^H
pro xterm
pro vymazání a
právě jste napsali na její obrazovku a stále nic neodesílá do aplikace, která čte ze strany slave, pouze aktualizuje vnitřní vyrovnávací paměť editoru řádků, aby odstranila a
již jste napsali.
Poté, když stisknete Enter, xterm odešle ^M
(CR), kterou řádková disciplína převede na vstupu na ^J (LF) a odešle to, co jste dosud zadali, ke čtení na podřízené straně (aplikace načtená na /dev/pts/x obdrží to, co jste zadali, včetně LF, ale nikoli
a
protože jste jej smazali), zatímco na hlavní straně odešle CR a LF pro přesun kurzoru na další řádek a začátek obrazovky.
Řádková disciplína je také zodpovědná za odeslání SIGINT
signál do skupiny procesů v popředí terminálu když obdrží ^C
postava na hlavní straně atd.
Mnoho interaktivních terminálových aplikací deaktivuje většinu funkcí této linie disciplíny, aby ji sami implementovali. V každém případě si však dejte pozor, aby terminál (xterm
) se na tom málo podílí (kromě zobrazení toho, co má zobrazovat).
A může existovat pouze jedna relace na proces a na koncové zařízení. K relaci může být připojen řídicí terminál, ale nemusí (všechny relace začínají bez terminálu, dokud jej neotevřou). xterm
, v procesu, který se rozvětvuje, aby spustil váš shell, obvykle vytvoří novou relaci (a proto se odpojí od terminálu, kde jste spustili xterm
z pokud existuje), otevřete nový /dev/pts/x
vytvořilo se připojením tohoto koncového zařízení k nové relaci. Poté v tomto procesu spustí váš shell, takže váš shell se stane vůdcem relace. Váš shell nebo jakýkoli interaktivní shell v této relaci bude obvykle žonglovat se skupinami procesů a tcsetpgrp()
, pro nastavení úloh na popředí a na pozadí pro daný terminál.
Pokud jde o to, jaké informace ukládá koncové zařízení s disciplínou tty (sériový nebo pty) , to je obvykle to, co stty
příkaz zobrazí a upraví. Veškerá konfigurace disciplíny:velikost obrazovky terminálu, místní, vstupní výstupní příznaky, nastavení pro speciální znaky (jako ^C, ^Z…), vstupní a výstupní rychlost (neplatí pro ptys). To odpovídá tcgetattr()
/tcsetattr()
funkce, které se v Linuxu mapují na TCGETS
/TCSETS
ioctls a TIOCGWINSZ
/TIOCSWINSZ
pro velikost obrazovky. Můžete namítnout, že aktuální skupina procesů v popředí je jiná informace uložená v koncovém zařízení (tcsetpgrp()
/tcgetpgrp()
, TIOC{G,S}PGRP
ioctls), nebo aktuální vstupní nebo výstupní vyrovnávací paměť.
Upozorňujeme, že informace o velikosti obrazovky uložené v koncovém zařízení nemusí odpovídat skutečnosti. Emulátor terminálu to obvykle nastaví (prostřednictvím stejného ioctl na hlavní velikosti), když se změní velikost jeho okna, ale může se nesynchronizovat, pokud aplikace zavolá ioctl na podřízené straně nebo když se změna velikosti nepřenese (v případě připojení ssh, které implikuje další pty vytvořený sshd
pokud ssh
ignoruje SIGWINCH
například). U některých terminálů lze také zjistit jejich velikost pomocí escape sekvencí, takže aplikace se na ně může tímto způsobem dotazovat a aktualizovat řádovou disciplínu pomocí těchto informací.
Pro více podrobností se můžete podívat na termios
a tty_ioctl
například manuálové stránky v Debianu.
Chcete-li si hrát s jinými řádkovými disciplínami:
-
Emulujte myš pomocí pseudoterminálu:
socat pty,link=mouse fifo:fifosudo inputattach -msc mouse # nastaví disciplínu MOUSE line a specifikuje protokolxinput list # viz nová myš thereexec 3<> fifoprintf '20712
Rozdíl mezi vestavěným příkazem a příkazem, který není? Automatizace webových požadavků pomocí Curl?Linux