Terminál FAQ programozók számára
K: Mi a smacs és a rmacs?
V: Terminvezérlő szekvenciák, 'start alternate character set' és
'end alternate character set'. Ezeket lehet használni
a 'grafikus' karakterek előcsalogatására, amilyeneket
a Midnight Commander használ.
Például 'linux' terminálon: smacs=ESC[11m, rmacs=ESC[10m;
'rxvt' terminálon: smacs=^N, rmacs=^O.
K: Honnan is lehet ezeket tudni?
V: Az infocmp <termináltípus> válaszából.
K: És ez mindig működik?
V: Hát, például az rxvt esetében az
enacs szekvenciát is használni kell előtte.
Vagy megerőszakolni az rxvt forrásprogramját (screen.c):
volt: MEMSET(charsets, 'B', sizeof(charsets));
lett: MEMSET(charsets, 'B', sizeof(charsets)); charsets[1]= '0';
Vagy megerőszakolni az rxvt termináltípus definícióját:
# infocmp rxvt >rxvt.ti
volt: smacs=^N
lett: smacs=\E)0^N
# tic rxvt.ti
K: És ha mindent jól beállítottam, működni fog
a karaktergrafika az emulátoromban?
V: Ez nincsen kizárva, de lehetnek buktatók, például
PuTTY-ban
UTF8 esetén kell egy külön beállítás, hogy működjön:
Window /
Translation /
Enable VT100 line drawing even in UTF-8
K: Kezdem úgy érezni, hogy az egész nem is annyira egzakt tudomány,
mint amilyennek látni szeretnénk... Van erre egy kipróbálóprogram?
V: Itt van: shchars.c
K: És a
tput-tal hogy van ez?
V: A
smacs és
rmacs paraméterekkel dolgozhatsz:
$ tput smacs
<olvasható vagy olvashatatlan szöveg>
$ tput rmacs
<normál állapot>
K: És még milyen paramétereket használhatok a tput-tal,
amik a manuáljában nincsenek?
V: A
terminfo(5) manualban lévőket,
itt van néhány lehetőség az ESC-szekvenciával együtt:
hatás bekapcs kódnév kikapcs kódnév megjegyzés
alternatív ? smacs ? rmacs emulátorfüggő, esetleg enacs is kell hozzá
betűkészlet
előtérszín ESC[30+nm - - - n=szín sorszáma (0..7;9=alapértelmezés)
háttérszín ESC[40+nm - - - n=szín sorszáma (0..7;9=alapértelmezés)
aláhúzás ESC[4m smul ESC[24m rmul
inverz ESC[7m smso ESC[27m rmso
vastag betű ESC[1m bold ESC[21m - hatása emulátorfüggő
villogás ESC[5m blink ESC[25m - hatása emulátorfüggő
alaphelyzet ESC[0m sgr0 - - színek alaphelyzetbe, spec. hatások kikapcsolása
K: Ha egy ilyen szekvenciában egy
%p1%d-szerű részt látok,
annak van valamilyen speciális jelentése?
V: Igen, oda változó paramétert kell beilleszteni
(esetünkben az első változó paramétert, decimális számként).
Programban erre használható a
tparm vagy a
tiparm függvény.
K: Ha esetleg egy
$<100/>
szerű szekvencia jelenik meg a képernyőmön, akkor annak is lehet köze a terminfóhoz?
V: Ez előfordulhat, ugyanis terminfo-nyelven ezek a szekcenciák
várakozást
jelentenek (a szám ezredmásodpercben értendő). Ha történetesen egy program erről nem tud,
és a szekvenciát egyben kiküldi a terminálnak, akkor persze joggal csodálkozol, hogy mit is látsz.
K: Mikor lenne szükség ilyen várakozásra?
V: Itt van például a
flash művelet:
ez először inverzre állítja a képet, aztán vár, aztán visszaállítja a normál képet:
$ infocmp xterm | grep flash
flash=\E[?5h$<100/>\E[?5l
$ tput flash | od -tx1
1b 5b 3f 35 68 1b 5b 3f 35 6c # a várakozás itt nem látszik!
ESC [ ? 5 h ESC [ ? 5 l
K: Ha én programban a
tigetstr-vel kiolvasok
egy ilyen szekvenciát, és azt ki akarom iratni, akkor az abban esetleg benne
lévő várakozásokat nekem kell kezelnem?
V: Megteheted, de van rá kész függvény is,
putp illetve
tputs néven.
K: Még valami hasznos funkció a tput-tal?
V: Például a
LINES és a
COLUMNS változók beállítása,
ha valamiért nem történt meg automatikusan:
$ export COLUMNS=$(tput cols); export LINES=$(tput lines)
K: Ezt vajon hogy csinálja a tput?
V: A kerneltől kérdezi meg, a TIOCGWINSZ nevű ioctl-vel.
Ugyanezt teszi a stty size parancs is.
Ennek párja a TIOCSWINSZ, amivel átállítod a kernel által ismert
méretet.
K: Milyen paranccsal használhatom ezt a TIOCSWINSZ ioctl-t?
V: A stty(1) való erre:
stty rows <sorok> columns <oszlopok>
Ne felejtsd el, ennek semmi hatása nincs a terminál(emulátor)ra,
csak a kernel által tárolt méretekre.
Továbbá nem állítja a COLUMNS/LINES változókat sem.
K: Ez azt jelenti, hogy a kernel számon tartja az emulált terminálokat?
V: Igen, minden (valós vagy emulált) terminálnak nyilvántartja a beállításait,
hogy a tiéd melyik, azt a tty(1) vagy a ttyname(3) adja meg. Próbáld ki:
$ tty
/dev/pts/9
$ ls -l $(tty)
crw--w---- 1 user tty 136, 9 Aug 30 15:59 /dev/pts/9
K: Hogyan 'születik' egy ilyen virtuális terminál?
V: Programból lehet létrehozni (a részletekért lásd a pty(7) manualt),
példa ezt használó programokra: xterm, telnetd, sshd, script, expect, ttyrec.
K: Hogyan lehet azt megoldani, hogy a kernel értesítsen,
ha átméretezték az ablakomat?
V: A kernel SIGWINCH
signalt küld azoknak a folyamatoknak,
akiknek a terminál a 'controlling terminal'-ja, és van signal-handlerük
erre a signal-ra (az alapértelmezés az ignore).
K: És még mire jó ez a stty?
V: Minden helyi beállítást ezzel szabályozhatsz, számtalan opciója van,
például:
$ savestty=$(stty -g) # minden beállítás elmentése
$ stty $savestty # elmentett beállítások visszaállítása
$ stty -a # minden beállítás kiírása (human-readable formátumban)
K: Közvetlenül a terminál(emulátor)tól is meg lehet kérdezni az ablakméretet?
V: Lehet, a következő ESC-szekvenciákkal:
kérdés: ESC[18t
válasz: ESC[8;<sorok>;<oszlopok>;t
kérdés: ESC[14t
válasz: ESC[4;<pixelsorok>;<pixeloszlopok>;t
K: Átméretezni is lehet így?
V: Terminálfüggő, ha lehet, akkor ezek valamelyikével:
ESC[8;<sorok>;<oszlopok>;t
ESC[4;<pixelsorok>;<pixeloszlopok>;t
K: Van erre a célra program is?
V: A neve
resize a neve, használata:
# lekérdezés:
$ resize -s
# beállítás; egyszerű meghívás, univerzális:
$ resize -s <oszlopok> <sorok>
# "trükkös" meghívás, egyes shell-ek esetén COLUMNS+LINES is állítódik
$ eval $(resize -s <oszlopok> <sorok>)
K: Mindezekből a részletekből hogy lehetne valami komplett
funkciót kihozni?
V: Például egy ilyen shell-függvényt lehetne írni:
termsize () {
if [ $# -eq 2 ]; then
eval $(resize -s "$1" "$2")
else
eval $(resize -s)
fi;
stty rows "$LINES" columns "$COLUMNS"
}
K: Fentebb volt szó
smacs /
rmacs szekvenciákról.
Kicsit pontosabban mit is csinálnak ezek?
V: Átváltják a terminált pszeudografikus karakterkészletre és vissza.
Ez kétféleképpen történhet: vagy a G0 és G1 között kapcsolnak oda-vissza,
vagy a G0-t állítják át a normál és a grafikus karkaterkészlet között.
K: Mi lenne a
G0 és
G1?
V: Először is a terminál/emulátor több karakterkészletet ismer(het):
kód jelentés
0 pszeudografikus karakterkészlet
A ASCII/UK (módosított ASCII)
B ASCII
stb Különféle módosított ASCII változatok
A gyakorlatban elég a 'B'-t és a '0'-t megjegyezni (a többinek akkor volt jelentősége, amikor
csak a 7-bites ASCII kód egyéni módosításaival lehetett a nemzeti karaktereket előállítani).
Ezeknek a kódoknak az alábbi ESC-szekvenciákban van jelentősége:
ESC ( C G0 beállítása, pl. ESC(B -> G0=ASCII (ez a szokásos beállítás G0-ra)
ESC ) C G1 beállítása, pl. ESC)0 -> G1=grafikus (ez meg G1-re a szokásos beállítás)
A teljesség kedvéért említsük meg, hogy egyes terminálok ismernek G2 és G3 készleteket is.
K: Tehát akkor mi is lenne a
G0 és
G1?
V: Tekintsük őket egy
indirekciós szintnek:
a fenti szekvenciákkal beállítjuk, hogy mit jelentsen a G0 és G1,
utána beállítjuk a terminált, hogy G0-t vagy G1-et használja:
SO (0x0e) Váltás G1-re (DEC)
SI (0x0f) Váltás G0-ra (DEC)
ESC[10m Váltás G0-ra (csak 'linux' terminál)
ESC[11m Váltás G1-ra (csak 'linux' terminál)
K: És akkor mik is ezek a grafikus karakterek?
V: Például olyasféle grafikus karakterek, amiket a
Midnight Commander használ a keretek kirajzolásához.
Ilyesmi lenne a listájuk:
kód graf.char hely. név
2b + → > ACS_RARROW
2c , ← < ACS_LARROW
2d - ↑ ^ ACS_UARROW
2e . ↓ v ACS_DARROW
30 0 █ # ACS_BLOCK
60 ` ♦ + ACS_DIAMOND
61 a ░ : ACS_CKBOARD
66 f ° ' ACS_DEGREE
67 g ± # ACS_PLMINUS
68 h ▒ # ACS_BOARD
69 i ¤ v § # ACS_LANTERN
6a j ┘ + ACS_LRCORNER
6b k ┐ + ACS_URCORNER
6c l ┌ + ACS_ULCORNER
6d m └ + ACS_LLCORNER
6e n ┼ + ACS_PLUS
6f o ⎺ ~ ACS_S1
70 p ⎻ - ACS_S3
71 q ─ - ACS_HLINE
72 r ⎼ - ACS_S7
73 s ⎽ - ACS_S9
74 t ├ + ACS_LTEE
75 u ┤ + ACS_RTEE
76 v ┴ + ACS_BTEE
77 w ┬ + ACS_TTEE
78 x │ | ACS_VLINE
79 y ≤ < ACS_LEQUAL
7a z ≥ > ACS_GEQUAL
7b { π * ACS_PI
7c | ≠ ! ACS_NEQUAL
7d } £ f ACS_STERLING
7e ~ ∙ o ACS_BULLET
A lista tartalmaz egy úgynevezett
helyettesítő karaktert is,
ezt akkor látjuk, ha a terminál nem tudja a grafikus karaktert
megjeleníteni.
Megj: Természetesen az is lehet, hogy a böngésződ sem tudja
ezek egyikét-másikát megjeleníteni, például a ACS_S1, ACS_S3, ACS_S7, ACS_S9
nem szokott megjelenni (bár az Unicode-ban benne vannak: U+23BA..U+23BD).
Megj: Az ACS_LANTERN jelentése nem egészen tiszta,
maga a szó
lámpást jelent,
szerintem a '¤' (U+A4) vagy a '§' (U+A7) jelre utalhat,
a ncurses szerint viszont az U+2603 kódú ☃ karaktert
(hóember).
K: Ezek a karakterek fixen ezeken a kódokon vannak?
V: Természetesen nem,
linux termináltípus esetén
más pozíciókon vannak (az IBM CP437 kódkészletéhez igazodva).
K: És ezt hogyan kezeljem a programomból?!
V: Lekérdezheted a terminfo-ból
acsc,
illetve termcap-ból
ac néven.
Ekkor egy karakterpárokból álló listát kapsz, amivel szabványos kódról terminál-specifikusra fordíthatsz.
K: Ez most komoly, vagy itt van valahol egy
kandi kamera?
V: Általában nem neked kell ezt csinálnod, hanem rábízhatod a ncurses nevű komponensre, pl:
addch (ACS_ULCORNER);
K: A terminál(emulátor) az egérkattintást is elküldi a szervernek?
V: Igen, ha a szerver ezt kéri tőle:
ESC[?9h -- X10 protokoll szerinti jelentés
(csak az 1-3 gombok lenyomása küld szekvenciát)
ESC[?1000h -- X11 protokoll szerinti jelentés
ESC[?1002h -- mint az előbbi,
de a 'vonszolás' (gombnyomás+mozgás) is küld szekvenciát
ESC[?1003h -- mint az előbbiek,
de a 'síma' mozgás is küld szekvenciát
ESC[?<n>l -- kikapcsolás (az előbb számok bármelyike használható)
Ennek hatására a terminál a következő szekvenciát küldi gombnyomás/felengedéskor:
ESC[M<kód><xpos><ypos>
<kód>: <valami> + 0x20 + <módosítók> + <gombsorszám>
módosítók (csak X11 protokoll esetén, emulátorfüggő):
0x04: Shift
0x08: Alt (vagy Meta)
0x10: Control
gombsorszám (a <valami> értékétől is függően):
0: bal
1: középső
2: jobb
3: felengedés
0x40: 4. gomb / görgő fel
0x41: 5. gomb / görgő le
0x42: 6. gomb / görgő-2 balra
0x43: 7. gomb / görgő-2 jobbra
valami:
0x00: (alapeset) 1-3 gomb lenyomás/felengedés
0x20: vonszolás (mozgás gomblenyomással) / mozgás
xpos,ypos:
0x20 + koordináta (1..223)
Persze ez csak egy kivonatos részlet, ennél sokkal több és bonyolultabb
lehetőség is van (ez persze az emulátorunktól is függ).
Arra is jó esély van, hogy pl a Shift-et az emulátor arra használja,
hogy mégse küldje a szervernek az egérszekvenciákat, hanem kijelölésre
szolgáljon az egér.
Megj: Látható, hogy a gombok felengedéséről csak korlátozottan értesülünk:
csak X11 protokoll esetén, csak az első három gomb esetén,
és még akkor sem jön az az információ, hogy
melyik gombot engedték fel.
K: Nincs olyan továbbfejlesztett üzemmód,
ami nem korlátozza a képméretet 226x226-ra?
V: Hogyne lenne?!
Három lehetőség is van,
ezek közül az emulátorod nullát vagy többet ismer.
kódnév bekapcsolás korlát
EXT ESC[?1005h 2015
SGR ESC[?1006h nincs
URXVT ESC[?1015h nincs
K: Mi az a scrolling region?
V: Egy sortartomány a terminálon, amely legalább két sorból áll,
de lehet a terminál egésze is, amelyen kívül semmilyen scrollozás nem történik.
K: Miféle scrollozás?
V: Például ha a line-wrap funkció a scrolling region utolsó sorában történik,
akkor az egész scrolling régió felfelé léptet, a legfelső sora elvész,
legalul pedig új (üres) sor keletkezik. Azután van néhány ESC-szekvencia, pl:
Insert Line (IL) ESC [ n L Sor(ok) beszúrása
Delete Line (DL) ESC [ n M Sor(ok) törlése
Index (IND) ESC D Kurzor le / scroll fel
Reverse Index (RI) ESC M Kurzor fel / scroll le
Next Line (NEL) ESC E Kurzor a következő sor elejére / scroll fel
Linefeed (LF) LF Soremelés / scroll fel
Reverse Linefeed ESC I Kurzor fel / scroll le
Megj: A 'reverse linefeed' meg a 'reverse index' nagyon egyformának tűnik;
a 'linefeed' működése egyes beállítások esetén megegyezik a 'next line'-éval.
K: Egyéb érdekesség a scrolling regionról?
V: Például, hogy relatív kurzorpozícionálással (pl. ESC[A, ESC[B, ESC[C, ESC[D)
csak belemenni lehet, kilépni belőle nem; sőt van olyan üzemmód,
amelyben abszolút pozícionálással (ESC[r;cH) sem,
(ebben a módban az első sor scrolling region első sorát jelenti).
K: Hogyan kell kijelölni a scrolling regiont?
V: Ezek a szekvenciák a barátaid:
ESC [ firstrow;lastrow r s.r. kijelölése
ESC [ r s.r. a teljes képernyő
ESC c terminál alapállapotba (s.r. a teljes képernyő)
ESC [ ? 6 h kurzor bezárása a s.r.-be
ESC [ ? 6 l az előbbi ellenkezője
K: És mire is jó ez a scrolling region?
V: Képzeljünk el egy olyan alkalmazást (mondjuk egy szövegszerkesztőt
vagy kalandjátékot), ahol a kép tetején és/vagy alján fix információs sorok vannak,
középen pedig egy scrollozódó adatrész.
K: Mi a különbség a unixos és Windows-os telnet-kliens között?
V: Számos különbség lehet, de a legnyilvánvalóbb az,
hogy a unixos kliens egy terminál(emulátor)on belül fut,
a Windows-os pedig egybe van építve a terminálemulátorral.
Rendszerint több különböző termináltípust képes emulálni (részben vagy egészben),
de az is lehetséges, hogy több különböző terminál ESC-szekvenciáinak
az unióját kezeli (már ahol ezek nem mondanak ellent egymásnak).
K: Igaz, hogy a telnet kliens és szerver
metainformációkat is küldözgetnek egymásnak,
amit a felhasználó nem lát?
V: Hogyne, vegyük például ismét az átméretezést:
amikor átméretezed a kliens ablakát, az egy ilyen üzenetet küld a szervernek:
byte kódnév
---- ------
FF IAC (interpret as command)
FA SB (subnegotiation)
1F NAWS (window size)
xh width (msb)
xl width (lsb)
yh height (msb)
yl height (lsb)
FF IAC (interpret as command)
F0 SE (subnegotiation end)
K: Honnan tudom meg, hogy hány színt lehet használni az emulált terminálon?
K: A tput colors paranccsal.
K: Ami megkérdezi a termináltól...
K: Nem, a TERM változóból és terminfo adatbázisból dolgozik, pl:
$ TERM=rxvt tput colors
8
$ TERM=rxvt-256color tput colors
256
$ TERM=vt102 tput colors
-1
Megjegyzés: az a nyolc szín lehet éppen 16 is, mivel egyes emulátorok
a 'bold' (vastag betűs) módot fényes tintaszínnel helyettesítik,
és/vagy a 'blink' (villogó) módot fényes papírszínnel.
K: A programok ugyebár a TERM változó és a terminfo adatbázis alapján
működnek, így nagyon flexibilisen alkalmazkodnak az aktuális helyzethez.
V: Abszolúte. De hogy egy kicsit árnyaljam a dolgot,
bizony néha behardkódolt szekvenciák és saját konfigfájlok is szerepelnek a történetben.
K: Például a Midnight Commander esetében?
V: Igen, a Midnight Commander a 'Learn Keys'
funkcióval megtanított szekvenciákat
egy konfigfájlban tárolja (pl. ~/.config/mc/ini),
ezeknek prioritása van a terminfóból származó értékek felett.
K: Vagy a bash.
V: Igen, a bash, és általában a
readline-t használó programok
a
~/.inputrc és
/etc/inputrc
fájlokból tájékozódnak,
ezek kibővíthetik/felülbírálhatják a terminfo adatait.
Bash-ban próbáljuk ki a
bind -P parancsot
az aktuális állapot lekérdezésére.
Megj: Egy kis inputrc-részlet, csak kedvcsinálónak:
# allow the use of the Home/End keys -- linux/vt100/xterm/rxvt
"\e[1~": beginning-of-line
"\e[7~": beginning-of-line
"\e[H": beginning-of-line
"\eOH": beginning-of-line
"\e[4~": end-of-line
"\e[8~": end-of-line
"\e[F": end-of-line
"\eOF": end-of-line
K: Mi szükség lehet ilyen trükkökre?
V: Például: a TERM rosszul van beállítva; a terminfo adatbázis hibás;
az emulátor rosszul emulál; esetleg a terminál(emuláció) működése a történelem
folyán inkompatibilisen változott, és nem világos, hogy melyik fél melyiket
használja.
Ha például kiváncsi vagy, hogy hány xterm-szerű/xterm-alapú termináldefiníció
van a rendszerben, akkor próbáld ki ezt:
find /usr/share/terminfo/x/ -name 'xterm*'
(És az még a jobbik eset, amikor az új működés új nevet kap, a rosszabb az,
amikor ez névváltozás nélkül történik.)
K: Ha már a
bash-ról
és a
terminfo-ról esik szó: ha a bash-ban
nem működik a Ctrl+L és/vagy a hosszú parancsosorok nem több képernyősorban,
hanem egy sorban, vízszintesen scrollozva jelennek meg, az is terminfo-probléma lehet?
V: Igen: lehet, hogy a terminfo adatbázisod nem tartalmazza
a terminálod (helyes) leírását,
esetleg a rendszeredben egynél több terminfo van, és azok nem binárisan
kompatibilisek egymással (ilyet csak AIX-on tapasztaltam).
K: Igaz, hogy a terminfo meg a termcap ugyanaz?
V: Majdnem: a termcap elavult (kezdve azzal a koncepcióval,
hogy az összes ismert termináltípus leírása egy szöveges fájlban (/etc/termcap)
legyen benne), de a kompatibilitás megtartására a terminfo biztosít
termcap-kompatibilis függvényeket.
Programozói szempontból a két rendszer hasonló, pl:
Függvények
terminfo termcap jelentés
setupterm tgetent Inicializálás
tigetstr tgetstr string-típusú terminál-adat lekérdezése
tigetnum tgetnum numerikus terminál-adat lekérdezése
Funkcióazonosító stringek
terminfo termcap jelentés
clear cl képernyőtörlés
kmous Km egérjelentés engedélyezése
kbs kb backspace billentyű (terminál küldi)
kcuf1 kr kurzor jobbra billentyű (terminál küldi)
K: És ha nem használ terminfo-t, nem hívja a libreadline-t,
hanem csak síma gets/fgets van benne,
akkor azzal azért van valamilyen szerkesztési lehetősége a felhasználónak?
V: Használható pl. a BackSpace (visszatörlés) gomb.
K: Láttam már olyat, hogy mégsem volt használható, csak egy
^? vagy
^H jelent meg...
V: Ilyenkor a kernel említett adattartalma nincs szikronban a terminállal.
Egészen pontosan a
stty erase
(avagy
termios.c_cc[V_ERASE]) beállítás hibás.
Például ilyesmivel lehetne probálkozni (valamilyen profile scriptben):
case $TERM in
linux|putty*)
stty erase ^?
;;
xterm*|rxvt*)
stty erase ^H
;;
esac
Egy flexibilisebb megoldás:
if [ -n "$TERM" ]; then
X=$(tput kbs) && stty erase "$X"
fi
Megj: egyes linux-változatok olyan meghaxolt terminfo
adatbázist használnak, amiben egyes termináltípusoknál (pl. rxvt)
a BackSpace beállítása eltér a
szokásostól,
hogy jobban idomuljon a linux-os alapértelmezéshez (ami a ^?) .
K: És kinek kellett volna ezt a stty-beállítást megtennie?
V: Tippem szerint annak a programnak, aki a virtuális terminált létrehozta,
ez például távoli belépés esetén a telnetd/sshd.
K: Programból ugyanez hogyan állítható?
V: A
termios(3) használatával.
A beállítások lekérdezése a
tcgetattr függvénnyel történik,
a módosítás a
tcsetattr függvénnyel,
az adatok egy
termios nevű struktúrába kerülnek. Pl:
struct termios t;
tcgettr (0, &t);
printf ("a kernel szerint a backspace kódja 0x%x", (unsigned char)t.c_cc[VERASE]);
K: Addig értem, hogy a különböző terminálok és emulációk
más-más szekvenciákat fogadnak, illetve küldenek;
de vannak-e további bonyolító tényezők?
V: Természetesen, itt van például a
Cursor Key Mode (DECCKM),
ez egy kétállású kapcsolót jelent, aminek állásától függően más-más
szekvenciát küldenek a nyíl-billentyűk:
bekapcs: ESC [ ? 1 h kikapcs: ESC [ ? 1 l
Up: ESC O A ESC [ A
Down: ESC O B ESC [ B
Right: ESC O C ESC [ C
Left: ESC O D ESC [ D
Home: ESC O H ESC [ H
End: ESC O F ESC [ F
Num5: ESC O E ESC [ E
Megjegyzés: az utóbbi három csak az xterm-re igaz, másoknál (pl rxvt)
a szekvencia nem ez (és nem is függ a CKM-től)
K: Valamint?
V: Van olyan is, hogy
Application Key Mode (DECKPAM),
ennek 'Application' és 'Numeric' állásai vannak, a numerikus billentyűzet
működését befolyásolja (emulátortól függ,
hogy csak a NumLock kikapcsolt állapotában-e, illetve, hogy NumLock működik-e
egyáltalán az 'Application' üzemmódban, esetleg csak Shift-tel együtt működik, stb.)
Application Numeric (NumLock-tól függően)
kapcs: ESC = ESC >
vagy: ESC[?66h ESC[?66l (ugyanaz, másképp)
0 ESC O p 0 | Insert
1 ESC O q 1 | End
2 ESC O r 2 | Down
3 ESC O s 3 | PgDn
4 ESC O t 4 | Left
5 ESC O u 5 | 'kb2'
6 ESC O v 6 | Right
7 ESC O w 7 | Home
8 ESC O x 8 | Up
9 ESC O y 9 | PgUp
NumLock (ESC O P) (működik)
/ ESC O Q /
* ESC O R *
- ESC O S -
+ ESC O l +
Enter ESC O M ^M
., ESC O n .,
K: Igaz, hogy a funkcióbillentyűk éppolyan összevissza vannak,
mint minden más a terminálokkal kapcsolatban?
V: Igaz.
K: Például egyes leírások húsz, vagy annál is több funkcióbillentyűről vélnek tudni.
Ez hogy jön ki?
V: Ha pl. Shift-tel együtt nyomsz le egy funkcióbillentyűt,
akkor az olyan, mintha 10-et hozzáadnál a billentyű sorszámához. Vagy 12-t.
Programtól függ. Pl a
ncurses-hez van egy tesztprogram,
annak a kimenete alapján:
billentyű ncurses xterm-szekvencia rxvt-szekvencia
F1 Key pressed: 0411 KEY_F(1) ESC O P ESC [ 11 ~
Shift+F1 Key pressed: 0425 KEY_F(13) ESC [ 1 ; 2 P ESC [ 23 ~
Ctrl+F1 Key pressed: 0441 KEY_F(25) ESC [ 1 ; 5 P ESC [ 11 ^
Ctrl+Shift+F1 Key pressed: 0455 KEY_F(37) ESC [ 1 ; 6 P ESC [ 23 ^
Az érdekesség kevéért a sorok végén feltüntettem két terminál-emulátor,
az xterm és az
rxvt
által generált ESC-szekvenciákat is.
K: Szóval itt 12-t adott hozzá a Shift a funkció-billentyű
sorszámához. És mikor van olyan, hogy 10-et ad hozzá?
V: Például a Midnight Commander használatáház praktikusabb, ha Shift+F5=F15, Shift+F7=F17
stb.
K: És ezt hogyan lehet elérni?
V: A derék mc saját erőből igyekszik alkalmazkodni a leggyakoribb termináltípusokhoz,
(ehhez lásd a
/usr[/local]/share/mc/mc.lib fájlban a
[terminal:] bejegyzéseket),
illetve a 'Learn Keys' funkcionalitással mi is segíthetünk neki.
K: Azt még értem, hogy mik azok az ESC-szekvenciák,
de mi az hogy CSI, SS3, ST meg a többi?
V: Vezérlőkarakterek 0x80 és 0x9f között,
gyakran (általában) kétbájtos szekvenciával helyettesítjük őket, pl:
Név Kód Helyette Utf8
SS3 8F ESC O C2 8F
DCS 90 ESC P C2 90
CSI 9B ESC [ C2 9B
ST 9C ESC \ C2 9C
OSC 9D ESC ] C2 9D
Megj: ha UTF-8-at használunk, akkor ezeket a vezérlőkódokat kétbájtos
szekvenciaként kell továbbítani, ezt a táblázat utolsó oszlopában láthatjuk.
Q: In
X Window, I wish to deactivate
key
NumLock.
A: Before
xkb extension you could do this:
numlockx on|off # pick the preferred value
xmodmap -e 'keycode 77 = '
With
xkb, I suggest swapping keycodes with a non-used key, eg:
numlockx on|off # pick the preferred value
/usr/bin/xkbcomp "$DISPLAY" /tmp/kbmap.xkb
sed -i.bak 's/<NMLK> = 77;/<NMLK> = 98;/
s/<KATA> = 98;/<KATA> = 77;/' /tmp/kbmap.xkb
/usr/bin/xkbcomp /tmp/kbmap.xkb "$DISPLAY"
Q: In Midnight Commander, if I press ESC key once,
it acts as if I pressed it twice. How can I deactivate this behaviour?
A: In menu
Options /
Configuration /
Esc key mode uncheck
Single press.
K: Milyen opciókkal érdemes fordítani?
V: Az én beállításaim:
./configure \
--prefix=/usr/local \
--enable-frills \
--enable-rxvt-scroll \
--enable-mousewheel \
--enable-256-color \
--with-term=rxvt-256color
K: Mit kell tudni az urxvt-ről?
V: Az rxvt egyik folytatása, itt található:
http://software.schmorp.de/pkg/rxvt-unicode.html
Saját termináltípusa(i):
rxvt-unicode és
rxvt-unicode-256color;
illetve használhatjuk a
rxvt és
rxvt-256color,
típusokat is, de vigyázzunk, mert a BackSpace terminfo-kódja különböző:
rxvt:
^H, rxvt-unicode:
^?
K: Ha mondjuk rxvt-256color típussal akarok repülni,
mit állítsak be?
V: Pl. ilyesmit tegyél a
~/.Xdefaults fájlodba:
Rxvt.termName: rxvt-256color
Rxvt.backspacekey: \010
Megj: Ennek persze kell egy
xrdb ~/.Xdefaults,
hogy érvényre jusson.
K: Milyen opciókkal érdemes fordítani?
V: Az én beállításaim:
./configure \
--prefix=/usr/local \
--enable-frills \
--enable-rxvt-scroll \
--enable-mousewheel \
--enable-256-color \
--with-term=rxvt-256color \
--disable-perl
K: Mit kell tudni a gnome-terminal-ról?
V: Kényelmesnek látszik, tab-okat kezel, UTF-8-képes;
idegesítő tulajdonsága, hogy lenyúlja az F1 és F10 gombokat;
korlátozottan konfigurálható
(X11-resource-ökkel nem, XML-konfig fájljai vannak);
van hozzá egy
gnome termináltípus,
de a
TERM változót nem arra állítja be,
hanem
xterm-re
(amellyel nem egészen kompatibilis).
Ezt úgy fixálhatjuk meg, ha az 'Edit / Profile Preferences / Title and Command'
menüben a Custom command-ot ilyesmire állítjuk:
sh -c 'TERM=gnome exec /bin/bash'
K: Mit kell tudni az
PuTTY-ról?
V: Ingyenes, elterjedt, jól használható, flexibilisen konfigurálható,
ssh-t is tudó program Windows-ra.
Honlapja:
http://www.chiark.greenend.org.uk/~sgtatham/putty/
Saját termináltípusa(i):
putty és
putty-256color a 'linux' típusra hasonlítanak legjobban
A beállításai közül érdekes lehet:
•
Window / Translation a távoli rendszer által használt kódolást állíthatjuk be,
összhangban a következő ponttal; ha a partner támogatja az UTF8-at, válasszuk azt.
•
Connection / Data / Environment variables a
LC_CTYPE-ot
az előző ponttal összhangban állítsuk be, pl.
hu_HU.UTF-8.
Más gyakran használt változókat is beállíthatunk itt, pl.
NLS_LANG,
LESSCHARSET,
TZ.
(Vö:
/etc/ssh/sshd_config-ban
AcceptEnv)
•
Terminal / Keyboard / TheHomeAndEndKeys: a 'standard' állást érdemes választani,
ugyanis abban a 'putty' termináltípussal kompatibilis, az 'rxvt' állásban viszont semmivel
(legkevésbé azt rxvt-vel:
Home: ESC[H End: ESC[0w).
•
Terminal / Keyboard / TheFunctionKeysAndKeypad:
- ESC[n~: a putty termináltípus szerint működik
- linux: a linux termináltípus szerint működik
- Xterm R6: az xterm-new termináltípus szerint működik,
kivéve a Home és End gombokat.
- VT400: (feltehetően) a vt400 termináltípus szerint működik,
különlegessége, hogy az Insert..PageDown blokkot a VT-terminálok mintájára átértelmezi
(lásd a függelékben).
- VT100+: (feltehetően) valamilyen VT-típus szerint működik.
- Sco: az xterm-sco termináltípus szerint működik.
K: Ha a mc-ben nem menne az egérgörgő
TERM=putty esetén, mit tegyünk?
V: Természetesen a mc forrását kell megpecselni,
pl. 4.8.11 esetén valahogy így:
cd lib/tty
cat >tty.patch <<DONE
111a112
> || strncmp (termvalue, "putty", 5) == 0
DONE
patch -i tty.patch tty.c
K: Valamiért a TERM változó értéke csupa nagybetű (pl PUTTY-256COLOR),
emiatt persze nem működik semmi!
V: Úgy tudom, hogy a kliensnek nagybetűt is kell küldenie,
és a szervernek lekicsinyítenie – de ha ez valamiért nem történik meg,
akkor megpróbálhatsz szervert cserélni, vagy protokollt cserélni (telnet helyett ssh),
vagy klienst cserélni, vagy olyan termináltípust beállítani, amiben nincs kötőjel.
K: A TERM-változóm jó, van is hozzá terminfo-bejegyzés
(különben 'Unknown terminal' üzenetet kapnék),
de mégsem mennek a grafikus karakterek (például a mc-ben)!
V: Lehet, hogy a terminfo-bejegyzés hiányos
(mert pl az őskorszakból származó egzotikus rendszered van),
szerezz be egy újabbat (egy működő rendszerről az
infocmp(1) programmal),
és telepítsd a tic(1) programmal.
K: Egzotikus rendszeremen (AIX) a bash
(vagy más, readline-t használó program) átméretezésnél lefagy!
V: A readline-t ne shared lib-ként fordítsd/telepítsd.
K: Mi lehet az oka annak, hogy a
mc-ben a keretrajzoló
karakterek (avagy grafikus karakterek) nem működnek?
V: Számos lehetőség van, pl:
* a TERM változó hibás, pl
putty esetén a
TERM=putty
(vagy
TERM=putty-256color) használandó
* a terminfo adatbázis hibás/hiányos,
szerezzünk be egy új definíciót a termináltipusunkhoz,
és a
tic(1) programmal telepítsük.
* a LC_CTYPE nincs beállítva, vagy nincs összhangban az emulátor beállításával;
putty esetén a Window/Translation/RemoteCharacterSet beállítással
összhangban lévő LC_TYPE-ot a Connection/Data/EnvironmentVariables menüpontban
definiálhatunk.
* a terminálunk kíván egy
enacs szekvenciát. Adjunk neki:
$ tput enacs
K: Ez a
LC_CTYPE
hogyan viszonyul az ssh-hoz?
V: Akkor működik legjobban, ha a
/etc/ssh/sshd_config
fájlban van egy ilyen sor (bejövő kapcsolatokhoz):
AcceptEnv LANG LC_*
a
/etc/ssh/ssh_config
fájlban pedig egy ilyen (kimenő kapcsolatokhoz):
SendEnv LANG LC_*
key | terminfo(5) kódnév | xterm sco | xterm new | xterm old | rxvt, Eterm | putty | linux | vt100
|
---|
Ins | kich1
| ESC[L | ESC[2~
|
---|
Del | kdch1
| ^? | ESC[3~
|
---|
Home | khome
| ESC[H | | ESC[7~ | ESC[1~ | ESC[7~
|
---|
End | kend
| ESC[F | | ESC[8~ | ESC[4~ | ESC[8~
|
---|
PgUp | kpp
| ESC[I | ESC[5~
|
---|
PgDn | knp
| ESC[G | ESC[6~
|
---|
Up | kcuu1
| ESC[A
|
---|
Down | kcud1
| ESC[B
|
---|
Right | kcuf1
| ESC[C
|
---|
Left | kcub1
| ESC[D
|
---|
Shift+Up | sr
|
| ESC[1;2A
|
| ESC[a
| ESCOA
|
|
---|
Shift+Down | sf
|
| ESC[1;2B
|
| ESC[b
| ESCOB
|
|
---|
Shift+Right | kRIT
|
| ESC[1;2C
|
| ESC[c
| ESCOC
|
|
---|
Shift+Left | kLFT
|
| ESC[1;2D
|
| ESC[d
| ESCOD
|
|
---|
Ctrl+Up |
|
| ESC[1;5A
|
| ESCOa
| ESCOA
|
|
---|
Ctrl+Down |
|
| ESC[1;5B
|
| ESCOb
| ESCOB
|
|
---|
Ctrl+Right |
|
| ESC[1;5C
|
| ESCOc
| ESCOC
|
|
---|
Ctrl+Left |
|
| ESC[1;5D
|
| ESCOd
| ESCOD
|
|
---|
BkSpc | kbs
| ^H | ^?
|
---|
Num5 | kb2
| | ESC[E | | ESCOu | ESC[G | ESCOu
|
---|
Back-Tab | kcbt
| | ESC[Z | | ESC[Z |
|
---|
F1 | kf1
| ESC[M | ESCOP | ESC[11~ | ESC[[A | ESCOP
|
---|
F2 | kf2
| ESC[N | ESCOQ | ESC[12~ | ESC[[B | ESCOQ
|
---|
F3 | kf3
| ESC[O | ESCOR | ESC[13~ | ESC[[C | ESCOR
|
---|
F4 | kf4
| ESC[P | ESCOS | ESC[14~ | ESC[[D | ESCOS
|
---|
F5 | kf5
| ESC[Q | ESC[15~ | ESC[[E | ESCOt
|
---|
F6 | kf6
| ESC[R | ESC[17~ | ESCOu
|
---|
F7 | kf7
| ESC[S | ESC[18~ | ESCOv
|
---|
F8 | kf8
| ESC[T | ESC[19~ | ESCOl
|
---|
F9 | kf9
| ESC[U | ESC[20~ | ESCOw
|
---|
F10 | kf10
| ESC[V | ESC[21~ | ESCOx
|
---|
F11 | kf11
| ESC[W | ESC[23~ |
|
---|
F12 | kf12
| ESC[X | ESC[24~ |
|
---|
F13 | kf13
| ESC[Y | ESC[1;2P | ESC[25~ |
|
---|
F14 | kf14
| ESC[Z | ESC[1;2Q | ESC[26~ |
|
---|
F15 | kf15
| ESC[a | ESC[1;2R | ESC[28~ |
|
---|
F16 | kf16
| ESC[b | ESC[1;2S | ESC[29~ |
|
---|
F17 | kf17
| ESC[c | ESC[15;2~ | ESC[31~ |
|
---|
F18 | kf18
| ESC[d | ESC[17;2~ | ESC[32~ |
|
---|
F19 | kf19
| ESC[e | ESC[18;2~ | ESC[33~ |
|
---|
F20 | kf20
| ESC[f | ESC[19;2~ | ESC[34~ |
|
---|
Megjegyzések:
- A második oszlopban lévő kód akkor kell, ha a infocmp(1)
program outputjában keresünk.
Bővebb információ a terminfo(5) manuálban.
- A Num5 az a szekvencia, amit a NumLock kikapcsolt állapotában küld
a numerikus billentyűzeten lévő ötös.
- xterm és társai esetén a nyilak illetve a Home/End-gombok
szekvenciáiban némi határozatlanság érezhető; aszerint, hogy a CKM ki-vagy bekapcsolt
állapotát tekintik-e alapértelmezettnek (a táblázatban a kikapcsolt szerepel).
VT (részlet)
+--------+-----------------+ +----+----+----+----+
| Help | Do | |F17 |F18 |F19 |F20 |
+--------+-----------------+ +----+----+----+----+
+--------+--------+--------+ +----+----+----+----+
| Find | Insert | Re- | |PF1 |PF2 |PF3 |PF4 |
| | Here | move | | | | | |
+--------+--------+--------+ +----+----+----+----+
| Select | Prev | Next | | 7 | 8 | 9 | - |
| | Screen | Screen | | | | | |
+--------+--------+--------+ +----+----+----+----+
| Up | | 4 | 5 | 6 | ' |
+--------+--------+--------+ +----+----+----+----+
| Left | Down | Right | | 1 | 2 | 3 |Entr|
+--------+--------+--------+ +----+----+----+ |
| 0 | . | |
+---------+----+----+
Generált szekvenciák (Különféle üzemmódoktól függően)
Billentyű Szekvencia(szekvenciák) terminfo PC-ekvivalens
Help: CSI 28 ~ kf15 F15(?)
Do: CSI 29 ~ kf16 F16(?)
Find: CSI 1 ~ khome Home(?)
Insert Here: CSI 2 ~ kich1 Insert
Remove: CSI 3 ~ kdch1 Delete
Select: CSI 4 ~ kslt End(?)
Prev Screen: CSI 5 ~ kpp PageUp
Next Screen: CSI 6 ~ knp PageDn
Up: CSI A SS3 A ESC A kcuu1 Up
Down: CSI B SS3 B ESC B kcud1 Down
Right: CSI C SS3 C ESC C kcuf1 Right
Left: CSI D SS3 D ESC D kcub1 Left
PC (részlet)
+----+----+----+
|SyRq|ScLk|Brk |
+----+----+----+
+----+----+----+ +----+----+----+----+
|Insr|Home|PgUp| |NmLk| / | * | - |
+----+----+----+ +----+----+----+----+
|Del |End |PgDn| | 7 | 8 | 9 | + |
+----+----+----+ +----+----+----+ +
| 4 | 5 | 6 | |
+----+ +----+----+----+----+
| Up | | 1 | 2 | 3 |Entr|
+----+----+----+ +----+----+----+ |
|Left|Down|Rght| | 0 | . | |
+----+----+----+ +---------+----+----+