backspace ^H vagy ^?

 ( NevemTeve | 2014. január 11., szombat - 16:43 )

De komolyan, olvtársak, hogy van az, hogy az elmúlt 40-50 év még nem volt elég ahhoz, hogy megnyugtatóan rendeződjön ez a mélységesen mély probléma?

Most ne mondjuk azt, hogy a bash/readline/mc/egyéb program tök jól kezeli mindkettőt, hanem vegyük elő a legfelhasználóbarátságtalanabb programunkat (pl dash, ksh), és nézzük meg, hogy abban működik-e a BackSpace, vagy esetleg megjelenik helyette egy ^H vagy ^? szekvencia.

Többé kevésbe megoldás az, ha valamilyen profile-ba beteszünk valami ilyesmit: stty erase $(tput kbs), de miért nem történik ez automágikusan, amikor a telnetd (vagy hasonló) létrehozza a virtuális terminált? Nem találták a tcsetattr-nál a c_cc[VERASE]-t vagy a tgetstr("kb") lett volna túl nehéz?

Nem látom viszont megoldásnak azt, hogy az emulátorunk mást emuláljon, mint amit a terminfo előír, csak hogy a szerver kedvében járjunk; sem azt, hogy a szerveren meghaxoljuk a terminfo adatbázisát, hogy így teremtsük meg az inkompatibilitás újabb állomását.

Akkor mi marad? A következő eljárást javaslom:

1. telnet-eljünk be a szerverbe, és a login pillanatában nézzük meg, hogy működik-e a BackSpace (ugyanis ekkor még az "eredeti" állapottal találkozunk, nem volt stty, nincs readline, hogy segítsen, etc)

1a. ha nem, hanem helyette a terminálon ^H jelenik meg, akkor olyan TERM-típust kellene emulálnunk(*), amiben kbs=^? (pl rxvt [szerk: az rxvt mégsem ilyen, hanem pl linux, putty, gnome vagy konsole]) [Szerk: példa ilyen rendszerre: linux]

1b. ha nem, hanem helyette a terminálon ^? jelenik meg, akkor olyan TERM-típust kellene emulálnunk(*), amiben kbs=^H (pl xterm) [Szerk: példa ilyen rendszerre: AIX]

2. ha jól jelenik meg, akkor szerencsénk van, ehhez a szerverhez megfelelő TERM-típust emulálunk

(*) az emulátorok néha megengedik, hogy mást küldjünk be, mint amit ténylegesen emulálunk -- ez általában ellenjavalt, de néha szükséges. Mondjuk ha maga az emulátor hibás definíciót tartalmaz pl az 'xterm'-hez, akkor jobb ötlet nem a meglévőt kijavítani, hanem lemásolni a meglévő 'xterm-javitott' névre, de a szervernek nem ezt a nevet küldeni, csak simán azt, hogy 'xterm'

Szerk 20130114.0646: Ilyesmi programrésznek kellene szerintem lennie a telnetd-ben: http://dtelnet.sourceforge.net/setbkspc.c

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

1. telnet-eljünk be a szerverbe,

csak igy?

--
"Pontosan ez a ti bajotok. Ez a kurva nagy csőlátás. [...]" (bviktor)

minek mondja mindig, hogy csőbe töltve akinek a csőre töltve?

Nem, elotte rajzolhatsz pentagrammat is, meg aldozhatsz kecsket keresztutnal. Egyebkent pedig a telnet port vedheto a kulvilag felol a teszt idejere, utana meg le lehet szedni a komplett telnetd-t.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.

Azért telnet, mert történetesen én a dtelnet felől érkeztem a problémához, de valóban, a ssh-t is vizsgálnom kellene, ha már egyszer belekaptam a témába. A putty lenne a kézenfekvő lépés, de az (ha jól emlékszem a múltkori méréseimre) csak egy termináltípust emulál hibátlanul, a putty-t és a putty-256color-t (hoppá, akkor kettőt).

(Off: ez a komponens vajon jó lenne a dtelnet ssh-képessé tételéhez?: http://www.libssh.org/)

Zarojelben mondom, hogy mar a login prompt elott tortenik egy terminalbeallitas (legalabbis az AT&T-fele Unixokon, ahol a getty mukodesenek befolyasolasahoz van egy ttydefs nevu fajl), majd pedig miutan a getty beolvasta a usernevet, mielott meghivna a login-t, akkor tortenik egy masodik stty. Persze amikor halozatrol jelentkezel be, akkor a getty nem jatszik. Viszont valoszinuleg pont azert nem vacakolnak a telnetd/ftpd/rlogind/sshd-ben a kifinomult terminalbeallitassal, mert elvben az mar egyszer jol be lett allitva az original gepen a getty altal. (Arrol mar nem is beszelve, hogy a jo oreg terminalokon egy csomo ilyen parameter allithato volt a terminal sajat belso menujebol, ami viszont nem hatott arra, hogy a terminal vt100 maradt az utan is.)

Igazságod vagyon, amit írtam, az csakis a telnetd/sshd által szült terminálokra vonatkozik; a fizikai vagy kvázi fizikai terminálokra (linuxon tty1..ttyN) nem -- az előbbieknél a *getty kellene intézkedjen, az utóbbiaknál viszont fel sem merül, hogy milyen a termináltípus: a linux kernel 'linux' típusú teminált emulál, 'oszt jónapot'.

Próbából az agetty forráskódjába néztem be, az sem kérdezi a terminfo/termcap-ot, viszont van benne egy ilyen jópofaság:

switch (ascval) {
...
case BS:
case DEL:
case '#':
    cp->erase = ascval; /* set erase character */
...
}

vagyis alkamazkodik ahhoz, ami jön a dróton... (ha nem jön semmi, akkor marad a default ^?)

Teljesen f^Hjo.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.

Csak úgy mellékesen megemlítem, hogy a terminfo szerint az rxvt esetén kbs=^H lenne, csak a valóságban nem így működik; és ha egy resource-szel átállítom (Rxvt.backspacekey: ^H), akkor a sh-ben megszűnik működni a backspace...

A forrásba belenézve úgy látszik, hogy ő, amolyan oppurtunista módjára, az aktuális helyzethez alkalmazkodik (tcgetattr). Ez persze akkor lenne csudijó, ha a terminfo-ban is lenne egy rxvt-linux, amiben kbs=^? , mert így ez egy nagyfokú gányolás..

Csak nézem, nézem, de nem tudom eldönteni mit is szeretnél. :)
Itt nem csak a backspace használatáról van szó. Csináltam már olyan rendszert, ami soros terminál+ terminálszerver+telnet+alkalmazás útvonalon írta a betűket. A logint mindjárt hagyjuk is ki!
Ekkor befelé 8, kifelé 6 konverzión keresztül közlekednek a karakterek. Erre még rájön a /etc/profile és/vagy ~/.profile módosításai.
Némi bizonytalanság esetén a tput is2 is segíthet rendet rakni. Nálam olyan 4-8k volt! (Gondosan ügyelve a bugos IBM terminálokra!!)
Eljutottunk oda, hogy van egy konzolunk és egy alkalmazás - amiért idáig dolgoztunk - biztosan jól működik. Hurrá!
Olyan megfontolatlan ötlettől vezérelve, hogy másik alkalmazást is futtassunk, keletkeznek a meglepetések. A keretrajzoló karakterek, vagy a hl/color attribútumok kezeléset sem minden program végzi egyformán.
Tódíthatom tovább is. A linuxban alapban (opensuse) kiirtva a terminfo/tic támogatás, ha felrakom már másképp működik. Persze ehhez képest AIX-ben a termcapot irtották. :) A '95-ben kidolgozott putty->AIX/linux saját terminfómat szoktam fordítani, de már az is megváltozott. Új rendszer=új szívás. Jöhet az unicode lereszelés.
Szóval az lehet a helyes működés ismérve, ha
- készre reszelek egy rendszert és minden jól működik
- egy készre reszelt rendszerről átmegyek ssh-val egy másik hasonló/ugyanolyanra és minden ugyanúgy működik
Hol itt a probléma? :)

+1 info: egyes terminálok/emulátorok támogatják a DECBKM opciót:

ESC[?67h: Backspace gomb eredménye ^H
ESC[?67l: Backspace gomb eredménye ^?

A vt*** terminálokra a terminfo általában kbs=^H -t tartalmaz, kivéve a vt300 és vt320 típusokat. Nyilván ennek is van valami misztikus oka...

Mondjuk az, hogy esetleg azok tényleg így működtek? (Az rémlk, hogy a setup-jában lehetett állítani, hogy Ctrl-H vagy Ctrl-? legyen a BS, és olyankor asszem a Shift-BS (vagy Ctrl-BS? a fene se emlékszik így 25 év után) küldte a másikat. Arra már nem emlékszem, hogy az alapbeállítás melyiknél mi volt (de szerintem lehet a neten VT100-as meg VT320-as doksikat találni, ha éppen ez a kérdés)

Hogyne, a vt100.net tele van hasznos infóval... Csak az a gond, hogy a terminfo csak egy 'kbs' szekvenciát tartalmazhat termináltípusonként; az nem megy neki, hogy 'de ha a felhasználó emígy opciózta, akkor nem ez', vagy 'igen, de linuxon mégis mást csinál az rxvt, mint amit a saját terminfo-ja állít'...

Jelen pillanatba ez egyetlen utat abban látom, ha a programok pontosan azt küldik/várják, amit a terminfo mond (holdállástól, hangulattól és platformtól függetlenül), csak a termináltípust kell jól kiválasztani. (Mármint, ahol erre van lehetőség...)

Ezert fugg a legtobb progi a libtermcap/libncurses parostol. Vagy readline-tol, ami goto 1.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.

Xterm barátunkat lehet hangolni a következő resource-szal:

$ grep XTerm.ttyModes ~/.Xdefaults
XTerm.ttyModes: erase ^H

Ennek hatására az xterm elkezd ^H-t küldeni és a termios-t is átállítja (stty -a: erase=^H).

Az rxvt nem ennyire tündérke, neki csak olyanja van, hogy:

$ grep Rxvt.backspacekey ~/.Xdefaults
Rxvt.backspacekey: ^H

ami stty-t nem állít, vagyis egy dash/ksh esetén a backspace gomb egy ^H szekvenciát produkál

Szerk: elindítottam az urxvt nevű programot, az eredmény kissé vegyes:

stty-ban átállítja az erase-t, ez jó
a BackSpace lenyomása egy kétbájtos szekvenciát generál:

$ shkeys
^H                94 0x5e 0136
                  72 0x48 0110

Szerk: a következővel viszont tökéletes:

$ grep URxvt.backspacekey ~/.Xdefaults
URxvt.backspacekey: \010

Most úgy látom, hogy a konsole nevű termináltípus lesz a barátom; olyan értelemben, hogy ha a dtelnet-user szeretne linux-os (vagy más erase=^?) alapértelmezésű géphez connectálni, akkor azt ajánlom neki, hogy TERM=konsole beállítással repüljön, akkor a stty meg a terminfo összhangban lesz, és a mc-ben is működnek a Shift+Up, Ctrl+PgDn szerű funkciók. Remélem.

Azért mielőtt elkiabálnánk... konsole (valódi /usr/bin/konsole, nem emulált), export TERM=konsole, mc-4.8.11

Shift+F4=^[O2S hatása: Move (ami F16 hatására kellene történjen). Namostan történelmileg a Shift+F4 xterm-es logikával tényleg F16. De a mc ezt a kavart valahogy le tudja kezeleni, ha TERM=xterm van beállítva: végrehajtja az F14-hez tartozó műveletet (edit new file).

Note to self: lehet, hogy a slang-ot kellene hangolni (rövidesen slangolni) a dologhoz...

Szerk: Nem, azt nem használja ilyen értelmben a mc..
inkább ilyesmi: http://www.midnight-commander.org/ticket/1890

Note to self: Az Alt+funkcióbillentyű nem úgy kellene menjen, mint az Alt+rendesbillentyű...

pl Alt+A = ESC A ok, Alt+Up = ESC ESC [ A nem jó

Ez utobbi miert nem jo, minek kellene lennie helyette?
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.

Mert ez a szerver számára három karaktert jelent: egy darab (önálló, nem szekvencia-kezdő) ESC-et, egy '['-t és egy 'A'-t. Az újabb emulátorok (xterm-new pl) valahogy így jelzik a módosítókat a szervernek:

Up=\e[A, módosító+Up=\e[1;nA
F1=\eOP, módosító+F1=\eOnP
F5=\e[15;2~, módosító+F5=\e[15;n~

ahol n=1+(1 ha Shift lenyomva)+(2 ha Alt lenyomva)+(4 ha Ctrl lenyomva)

Persze nem ennyire egyszerű, pl a Shift+F1 emulátortól függően lehet \eO2P is meg \eO1;2P is, vagy esetleg \e[1;2P

És akkor ott vannak még a régi emulátorok, pl az rxvt-ben a Shift+Up \e[a, a Ctrl+Up \eOa, Alt-ot (és kombinációkat) nem kezel.

Vilagos, koszi.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.

Lett mindebből a kavarásból egy 1.3.1
https://sourceforge.net/projects/dtelnet/files/dtelnet/1.3.1/

Note to self: Az xterm ismer egy ptyInitialErase nevű resource-öt, rá kellene nézni.