IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)
Terminals, terminfo, ncurses
| Curs: | LinuxProgramacio |
| Fitxers: | ProgramacioC2.pdf (ProgramacioC2.odp), UD_8_2_comandes_inicials.pdf |
| Repositori SVN: | https://anonymous@svn.projectes.lafarga.cat/svn/iceupc/LinuxProgramacio |
| Usuari: | anonymous |
| Paraula de pas: | sense paraula de pas |
| Autors: | Sergi Tur Badenas, |
Nota sobre els exemples
Podeu obtenir el codi font de tots els exemples executant:
svn checkout https://svn.lafarga.cpl.upc.edu/dades/svn/plinux/sessio6
- Usuari:anonymous
- Paraula de pas:anonymous
Terminals
Els teletypes (o la seva abreviació tty) o teleprinters són els predecessors del terminals de video. Van ser els primers terminals de text i normalment consistien en aparells mecànics amb un màquina d'escriure directament connectada a una impressora:
Després van vindre els terminals de vídeo amb suport només per a text:
I actualment el que utilitzem són emuladors de terminals, o el que śe el mateix aplicacions que emulen el funcionament dels antics components de maquinari.
Tot i que els teleterminals són uns components obsolet a nivell de maquinari, el model conceptual que proposen es manté en els sistemes actuals Linux:
NOTA: És important tenir clar la diferència entre l'intèrpret d'ordres i les terminals. Sovint s'utilitzen els termes línia de comandes, terminal, shell, intèrpret de línia d'ordres, consola com si fossin la mateixa cosa. La terminal és el component de maquinari (antigues teletypes) o el programa que executa l'interpret de comandes o shell. Consulteu l'article LPI 103.1. Treballar a la línia d'ordres per tal d'obtenir més informació sobre la línia de comandes.
Recursos:
Teletypes o Teleprinters
Són el antecessors del concepte de terminal modern. Van apareixer als anys 20 i els primers sistemes eren sistemes completament mecànics formats per una màquina d'escriure connectada directament a una impressora. De fet ja existien sistemes predecessors de terminals remots (per l'any 1870) com una màquina Stock_ticker_machine que enviava les cotitzacions de la borsa de Nova York mitjançant el telègraf.
Recursos:
Terminals Virtuals
Els terminals virtuals (http://en.wikipedia.org/wiki/Virtual_console) també coneguts com consoles Virtuals són en GNU/Linux o altres sistemes similars com FreeBSD la combinació d'un teclat i una pantalla per a la comunicació (interfície) amb l'usuari. Són una desenvolupament més modern del que eren els antics teletypes (http://en.wikipedia.org/wiki/Teleprinter).
Com que els sistemes moderns són multiusuari i multitasca, els terminals virtuals proveeixen a un sistema operatiu de múltiples terminals independents entre si. Cada terminal śe una interfície d'usuari diferent.
Tal i com s'indica al fitxer /etc/inittab , que és el fitxer que llegeix el procés init en la majoria de sistemes Linux tenim 6 terminals de text:
- /dev/tty1
- /dev/tty2
- /dev/tty3
- /dev/tty4
- /dev/tty5
- /dev/tty6
NOTA: En sistemes basats en upstart no existeix el fitxer inittab però hi ha un procediment equivalent.
I un terminal d'entorn gràfic x:
- /dev/tty7
Actualment la necessitat de terminals ja no es tant important degut a que els entorns gràfics ja proveeixen de múltiples interfícies d'usuari. Per canviar entre terminals virtuals utilitzem la combinació de tecles Alt+Ctrl + Tecla de funció. Per exemple, per canviar al segon terminal virtual executem:
Ctrl+Alt+F2
A l'entorn gràfic podem obrir nous terminals amb emuladors de terminals com gnome-terminal o xterm. Si obrim una terminal en un entorn gràfic acabat d'iniciar i executem:
$ who -a -H
NOM LÍNIA HORA OCIÓS PID COMENT. EIXIDA
system boot 2007-05-13 17:24
nivll exec 2 2007-05-13 17:27 darrer=
LOGIN tty4 2007-05-13 17:27 4464 id=4
LOGIN tty5 2007-05-13 17:27 4465 id=5
LOGIN tty2 2007-05-13 17:27 4467 id=2
LOGIN tty3 2007-05-13 17:27 4471 id=3
LOGIN tty1 2007-05-13 17:27 4472 id=1
LOGIN tty6 2007-05-13 17:27 4473 id=6
sergi ? :0 2007-05-13 17:27 ? 5514
sergi + pts/0 2007-05-13 17:28 . 6514 (:0.0)
Als primers terminals virtuals s'està executant l'aplicació LOGIN i al 7 estem executant l'entorn gràfic. L'última línia ens mostra el emulador de terminal que hem executat des de l'entorn gràfic.
Si canviem a la consola virtual 2 executant:
Ctrl+Alt+F2
Introduïm l'usuari i contrasenya que ens demana l'aplicació i tornem a l'entorn gràfic amb
Ctrl+Alt+F7
Si ara tornem a executar:
$ who -a -H
NOM LÍNIA HORA OCIÓS PID COMENT. EIXIDA
system boot 2007-05-13 17:24
nivll exec 2 2007-05-13 17:27 darrer=
LOGIN tty4 2007-05-13 17:27 4464 id=4
LOGIN tty5 2007-05-13 17:27 4465 id=5
sergi - tty2 2007-05-13 17:36 . 4467
LOGIN tty3 2007-05-13 17:27 4471 id=3
LOGIN tty1 2007-05-13 17:27 4472 id=1
LOGIN tty6 2007-05-13 17:27 4473 id=6
sergi ? :0 2007-05-13 17:27 ? 5514
sergi + pts/0 2007-05-13 17:28 . 6514 (:0.0)
Veurem que la terminal virtual 2 ja no s'està executant l'aplicació LOGIN. Si repetim els passos però amb la consola virtual 3, però introduïm l'usuari i contrasenya d'una altre usuari (en aquest cas l'usuari bego) obtindrem el següent a l'executar who:
$ who -a -H
NOM LÍNIA HORA OCIÓS PID COMENT. EIXIDA
system boot 2007-05-13 17:24
nivll exec 2 2007-05-13 17:27 darrer=
LOGIN tty4 2007-05-13 17:27 4464 id=4
LOGIN tty5 2007-05-13 17:27 4465 id=5
sergi - tty2 2007-05-13 17:36 . 4467
bego - tty3 2007-05-13 17:37 . 4471
LOGIN tty1 2007-05-13 17:27 4472 id=1
LOGIN tty6 2007-05-13 17:27 4473 id=6
sergi ? :0 2007-05-13 17:27 ? 5514
sergi + pts/0 2007-05-13 17:28 . 6514 (:0.0)
Ara podem anar a una terminal virtual que encara no hagem utilitzat com la 1:
Ctr+Alt+F1
I executem:
startx -- :2 &
Això obrira una nova sessió del servidor X al DISPLAY 2. Obrim un terminal en aquest nou entorn gràfic i tornem a executar who:
$ who -a -H
NOM LÍNIA HORA OCIÓS PID COMENT. EIXIDA
system boot 2007-05-13 17:24
nivll exec 2 2007-05-13 17:27 darrer=
bego - tty4 2007-05-13 17:44 00:06 4464
LOGIN tty5 2007-05-13 17:27 4465 id=5
sergi - tty2 2007-05-13 17:36 00:14 4467
bego - tty3 2007-05-13 17:37 00:13 4471
sergi - tty1 2007-05-13 17:46 00:04 4472
LOGIN tty6 2007-05-13 17:27 4473 id=6
sergi ? :0 2007-05-13 17:27 ? 5514
sergi + pts/0 2007-05-13 17:28 . 6514 (:0.0)
sergi + pts/2 2007-05-13 17:46 00:03 7804 (:2.0)
A tty1 ja no està corrent l'aplicació LOGIN i tenim una nova aplicació de terminal (pts2) corrent dins l segon entorn gràfic (:2.0). Si disposem d'un altre ordinador o d'un altre persona per parelles podem provar de que algú es connecti es connecti a la nostra màquina executant:
ssh sergi@ip_del_nostre_ordinador
Un cop estigui dins si tornem a executar who:
$ who -a -H
NOM LÍNIA HORA OCIÓS PID COMENT. EIXIDA
system boot 2007-05-13 17:24
nivll exec 2 2007-05-13 17:27 darrer=
bego - tty4 2007-05-13 17:44 00:15 4464
LOGIN tty5 2007-05-13 17:27 4465 id=5
sergi - tty2 2007-05-13 17:36 00:23 4467
bego - tty3 2007-05-13 17:37 00:23 4471
sergi - tty1 2007-05-13 17:46 00:13 4472
LOGIN tty6 2007-05-13 17:27 4473 id=6
sergi ? :0 2007-05-13 17:27 ? 5514
sergi + pts/0 2007-05-13 17:28 . 6514 (:0.0)
sergi + pts/2 2007-05-13 17:46 00:13 7804 (:2.0)
sergi + pts/1 2007-05-13 17:55 00:04 6514 (:0.0)
sergi + pts/3 2007-05-13 17:55 00:02 6514 (:0.0)
sergi + pts/4 2007-05-13 17:57 00:02 6514 (:0.0)
sergi + pts/5 2007-05-13 17:57 00:02 8529 (ubuntu-sala.casa)
Veiem que hi ha un nova terminal pts (la pts5) i ens indica desde on s'ha connectat. La penúltima fila és l'identificador del procés:
$ ps aux | grep 8529 root 8529 0.0 0.2 7880 2396 ? Ss 17:57 0:00 sshd: sergi [priv] sergi 8811 0.0 0.0 2900 764 pts/0 R+ 18:02 0:00 grep 8529
Recursos:
Emuladors de terminal
Quantitat màxima de fitxers oberts al mateix temps:
$ cat /proc/sys/fs/file-max
Fitxers oberts en un moment concret:
$ cat /proc/sys/fs/file-nr
$ lsof | grep /dev/pts COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME bash 6524 sergi 0u CHR 136,0 2 /dev/pts/0 bash 6524 sergi 1u CHR 136,0 2 /dev/pts/0 bash 6524 sergi 2u CHR 136,0 2 /dev/pts/0 bash 6524 sergi 255u CHR 136,0 2 /dev/pts/0 bash 7807 sergi 0u CHR 136,2 4 /dev/pts/2 bash 7807 sergi 1u CHR 136,2 4 /dev/pts/2 bash 7807 sergi 2u CHR 136,2 4 /dev/pts/2 bash 7807 sergi 255u CHR 136,2 4 /dev/pts/2 ksnapshot 11049 sergi 0u CHR 136,0 2 /dev/pts/0 ksnapshot 11049 sergi 1u CHR 136,0 2 /dev/pts/0 ksnapshot 11049 sergi 2u CHR 136,0 2 /dev/pts/0 bash 20398 sergi 0u CHR 136,1 3 /dev/pts/1 bash 20398 sergi 1u CHR 136,1 3 /dev/pts/1 bash 20398 sergi 2u CHR 136,1 3 /dev/pts/1 bash 20398 sergi 255u CHR 136,1 3 /dev/pts/1 lsof 20434 sergi 0u CHR 136,1 3 /dev/pts/1 lsof 20434 sergi 2u CHR 136,1 3 /dev/pts/1 grep 20435 sergi 1u CHR 136,1 3 /dev/pts/1 grep 20435 sergi 2u CHR 136,1 3 /dev/pts/1 ...
Recursos:
Principals emuladors de terminal
Consulteu:
LPI_103.1._Treballar_a_la_línia_d'ordres#Principals_emuladors_de_terminal
Terminals remots
Consulteu SSH.
Comandes de terminals
NOTA: Per enviar missatges a l'entorn gràfic utilitzeu Zenity, notify-send,kdialog, Xdialog, dialog
wall
La comanda wall (write all) envia un missatge a totes les terminals:
# wall The system is coming down in ten minutes for unexpected maintenance. Please log off soon in order to save your files. <CTRL-d>
Es pot llegir de l'entrada estàndard o redireccionar amb una conducte (pipe):
$ echo "En 5 minuts aturem el sistema" | wall
O crear un fitxer i utilitzar-lo:
$ joe missatge En 5 minuts aturem el sistema.
$ sudo wall missatge
Per llegir d'un fitxer només es pot fer com a superusuari.
Recursos:
write
Permet enviar un missatge a un usuari en la mateixa màquina. Al sintaxi de write és:
$ write user [tty] missatge
Per acabar el missatge s'ha d'enviar un EOF (End of FILE) amb Ctrl+D (no és el mateix però també funciona Ctr+C). L'argument tty només es necessari si l'usuari esta logat en més d'una terminal
Exemple
$ write sergi write: sergi is logged in more than once; writing to pts/4 HOLA! EOF
L'usuari sergi a la pseudo-terminal pts/4 rep el següent missatge:
Message from sergi@casa-linux on pts/3 at 22:01 ... HOLA! EOF
Recursos:
talk
$ sudo apt-get install talk
mesg
Activa o desactiva els permisos d'accés d'escriptura de la resta d'usuaris a la teva terminal. Per consultar si permetem escriure o no executem:
$ mesg is y
Si volem desactivar els permisos executem:
$ mesg n
Si volem tornar a activar executem:
$ mesg y
Recursos:
ttysnoop
$ sudo apt-get install ttysnoop
Serveix per espiar terminals. Consulteu EspiarTerminals.
exit
Surt de la terminal.
clear
Neteja la pantalla del terminal però conserva el prompt:
$ clear
Recursos:
reset
Tornar a iniciar la terminal. Esborra tots els continguts inclòs el prompt:
$ reset
És equivalent a:
setterm -reset
Molt útil quan la terminal queda en mal estat, com per exemple després d'itentar mostrar un fitxer binari:
$ cat /bin/ps ␊⎼±␋@␌▒⎽▒-┌␋┼┤│:·/␍⎺␌⎽/ICE/2006-2007/P⎼⎺±⎼▒└▒␌␋⎺L␋┼┤│/⎽␊⎽⎽␋⎺6/␊│␊└⎻┌␊⎽/␍␋└⎺┼␋⎽$ ⎽␊⎼±␋@␌▒⎽▒-┌␋┼┤│:·/␍⎺␌⎽/ICE/2006-2007/P⎼⎺±⎼▒└▒␌␋⎺L␋┼┤│/⎽␊⎽⎽␋⎺6/␊│␊└⎻┌␊⎽/␍␋└⎺┼␋⎽$ ⎼␊⎽␊├
Escrivim reset (encara que sigui a cegues) i podem recuperar la terminal:
⎼␊⎽␊├ sergi@casa-linux:~/docs/ICE/2006-2007/ProgramacioLinux/sessio6/exemples/dimonis$
Recursos:
who
Mostra els usuaris que hi ha al sistema en un moment donat:
$ who sergi tty7 2009-04-18 15:05 (:0) sergi pts/0 2009-04-18 15:06 (:0.0) sergi pts/1 2009-04-18 16:40 (:0.0) bego tty9 2009-04-18 16:43 (:20) bego pts/2 2009-04-18 16:43 (:20.0) bego pts/3 2009-04-18 16:47 (:20.0) sergi pts/5 2009-04-18 18:27 (:0.0) sergi pts/6 2009-04-18 18:33 (:0.0) sergi pts/7 2009-04-18 18:39 (:0.0) sergi pts/8 2009-04-18 18:48 (:0.0)
La comanda who mostra quins usuaris estan autenticats i en quines terminals:
$ who -a -H
NOM LÍNIA HORA OCIÓS PID COMENT. EIXIDA
system boot 2007-05-13 17:24
nivll exec 2 2007-05-13 17:27 darrer=
LOGIN tty4 2007-05-13 17:27 4464 id=4
LOGIN tty5 2007-05-13 17:27 4465 id=5
LOGIN tty2 2007-05-13 17:27 4467 id=2
LOGIN tty3 2007-05-13 17:27 4471 id=3
LOGIN tty1 2007-05-13 17:27 4472 id=1
LOGIN tty6 2007-05-13 17:27 4473 id=6
sergi ? :0 2007-05-13 17:27 ? 5514
sergi + pts/0 2007-05-13 17:28 . 6514 (:0.0)
Llista únicament els noms de connexió i dóna el nombre total d’usuaris connectats.
$ who -q sergi sergi sergi sergi sergi nombre d’usuaris=5
Mostrar amb quin usuari estic connectat:
$ who am i sergi pts/1 2009-11-01 09:26 (:0.0)
o
$ whoami sergi
Recursos:
finger
La comanda finger és molt similar a la comanda who (mostra informació addicional sobre els usuaris). De fet és una comanda posterior i l'origen del seu nom esta relacionat amb que l'ús que feia la gent de who.
$ finger Login Name Tty Idle Login Time Office Office Phone sergi Sergi Tur Badenas *:0 May 17 07:58 sergi Sergi Tur Badenas pts/1 32 May 17 07:59 (:0.0) sergi Sergi Tur Badenas pts/0 May 17 11:14 (:0.0) sergi Sergi Tur Badenas pts/2 12 May 17 11:19 (:0.0)
La opció -l ens doca més informació sobre els usuaris;
$ finger -l Login: sergi Name: Sergi Tur Badenas Directory: /home/sergi Shell: /bin/bash On since Sat Apr 18 18:30 (CEST) on pts/0 from 87.111.152.17 6 minutes 15 seconds idle On since Sat Apr 18 18:40 (CEST) on pts/1 from 87.111.152.17 No mail. No Plan.
Recursos:
tty
Ens mostra la terminal sobre la que esta corrent el procés. Per exemple en un emulador de terminal, ens mostra:
$ tty /dev/pts/1
Els emuladors de terminals, utilitzen els fitxer de caràcters (fitxers especials o de dispositiu) de la carpeta /dev/pts. El número és el número de terminal que tenim obert.
Si ho executem en una terminal virtual (per exemple la 2, pressionant abans la combinació de tecles Alt+Crtl+F2) obtenim:
$ tty /dev/tty2
Recursos:
lsof
La comanda lsof mostra tots els descriptors de fitxers oberts. Si ho combinem amb grep la podem utilitzar per veure els descriptors de fitxers de les pseudo-terminals:
$ lsof | grep pts bash 20198 sergi 0u CHR 136,0 2 /dev/pts/0 bash 20198 sergi 1u CHR 136,0 2 /dev/pts/0 bash 20198 sergi 2u CHR 136,0 2 /dev/pts/0 bash 20198 sergi 255u CHR 136,0 2 /dev/pts/0 lsof 21074 sergi 0u CHR 136,0 2 /dev/pts/0 lsof 21074 sergi 2u CHR 136,0 2 /dev/pts/0 grep 21075 sergi 1u CHR 136,0 2 /dev/pts/0 grep 21075 sergi 2u CHR 136,0 2 /dev/pts/0
Recursos:
getty
Utilitzant al /etc/inittab per crear les terminals virtuals (/dev/ttyx) i executar login.
$ cat /etc/inittab 1:2345:respawn:/sbin/getty 38400 tty1 2:23:respawn:/sbin/getty 38400 tty2 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6
Recursos:
mingetty
migetty permet l'entrada automàtica d'un usuari i substitueix getty. El podeu instal·lar amb
$ sudo apt-get install mingetty
Ara per utilitzar-lo cal modificar el fitxer inittab:
#2:23:respawn:/sbin/getty 38400 tty2 2:2:respawn:/sbin/mingetty --autologin username tty2
Busqueu la línia que esta comentada i afegiu la que no ho esta. A username poseu el nom del usuari que voleu executar automaticament.
Fitxers
/etc/motd
Recursos:
/etc/inittab
NOTA: inittab a Ubuntu ha estat substituït per Upstart
A la següent secció d'aquest fitxer, es determinen les consoles virtuals del sistema:
$ cat /etc/inittab ................ # /sbin/getty invocations for the runlevels. # # The "id" field MUST be the same as the last # characters of the device (after "tty"). # # Format: # <id>:<runlevels>:<action>:<process> # # Note that on most Debian systems tty7 is used by the X Window System, # so if you want to add more getty's go ahead but skip tty7 if you run X. # 1:2345:respawn:/sbin/getty 38400 tty1 2:23:respawn:/sbin/getty 38400 tty2 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6 ........
Recursos:
Fitxers de dispositiu
A la carpeta /dev trobarem diferents fitxers de dispositius relacionats amb les terminals. Tal i com podem veure a la següent taula
Els fitxers d'aquesta carpeta són arxius especials, ja que no apunten a cap fitxer ni directori regular sinó que fan referència dispositius de maquinari reals o virtuals.
Primer observem les terminals virtuals (tty):
$ ls -la /dev/tty* | more crw-rw-rw- 1 root root 5, 0 2007-05-13 19:22 /dev/tty crw-rw---- 1 sergi sergi 4, 0 2007-05-13 19:26 /dev/tty0 crw------- 1 sergi tty 4, 1 2007-05-13 19:27 /dev/tty1 crw-rw---- 1 sergi sergi 4, 10 2007-05-13 19:26 /dev/tty10 ............................................................. crw------- 1 sergi tty 4, 2 2007-05-13 17:36 /dev/tty2 ............................................................ crw------- 1 bego tty 4, 3 2007-05-13 17:37 /dev/tty3 ............................................................ crw------- 1 bego tty 4, 4 2007-05-13 17:45 /dev/tty4 crw-rw---- 1 root root 4, 40 2007-05-13 19:26 /dev/tty40 ............................................................ crw------- 1 root root 4, 5 2007-05-13 17:27 /dev/tty5 ............................................................ crw------- 1 root root 4, 6 2007-05-13 17:27 /dev/tty6 ............................................................ crw-rw---- 1 root root 4, 7 2007-05-13 19:26 /dev/tty7 crw-rw---- 1 root root 4, 8 2007-05-13 17:27 /dev/tty8 crw-rw---- 1 bego bego 4, 9 2007-05-13 19:26 /dev/tty9 ............................................................
Una carpeta especial és la carpeta dev/pts. En aquesta carpeta hi ha un fitxer per cada emulador de terminal que estem utilitzant:
$ ls -la /dev/pts total 0 drwxr-xr-x 2 root root 0 2007-05-13 19:26 . drwxr-xr-x 16 root root 14240 2007-05-13 17:46 .. crw--w---- 1 sergi tty 136, 0 2007-05-13 18:39 0 crw--w---- 1 sergi tty 136, 1 2007-05-13 17:56 1 crw--w---- 1 sergi tty 136, 2 2007-05-13 17:47 2 crw--w---- 1 sergi tty 136, 3 2007-05-13 18:04 3 crw--w---- 1 sergi tty 136, 4 2007-05-13 17:57 4 crw--w---- 1 sergi tty 136, 5 2007-05-13 18:04 5 crw--w---- 1 sergi tty 136, 6 2007-05-13 19:42 6 crw--w---- 1 sergi tty 136, 7 2007-05-13 19:26 7
Variables d'entorn
TERM
La variable d'entorn TERM ens mostra el tipus de terminal que estem utilitzant. Si consultem el valor de la variable en un emulador de terminal en un entorn X obtindrem:
$ echo $TERM xterm
En canvi si l'executem en una terminal virtual (pressionant la combinació de tecles Alt+Ctrl+F1) obtindrem:
$ echo $TERM linux
Recursos:
Exemples
Com enviar el resultat d'una comanda a dues terminals diferents
Primer heu de consultar el nom de la terminal on voleu enviar el resultat amb:
$ tty /dev/pts/7
I ara utilitzeu tee:
$ ls -la | tee /dev/pts/7
Programació de terminals a baix nivell. termios
En sistemes compatibles POSIX existeix una capçalera, termios.h que permet controlar la terminal a baix nivell.
#include <termios.h> /usr/include/sys/termios.h /usr/include/termios.h
El més important de termios és la següent estructura de C:
struct termios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
};
I les funcions que ens permeten manipular aquesta estructura i així controlar la configuració del terminal a baix nivell.
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
int tcsendbreak(int fd, int duration);
int tcdrain(int fd);
int tcflush(int fd, int queue_selector);
int tcflow(int fd, int action);
Recursos
Exemple Noecho. No mostrar una Contrasenya
Veiem un exemple de com manipular les propietats d'un terminal per tal d'evitar l'echo al introduir una contrasenya:
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#define PASS_LEN 8
void err_quit(char *msg, struct termios flags);
int main()
{
struct termios old_flags, new_flags;
char password[PASS_LEN + 1];
int retval;
/* Obtenir la configuració actual del terminal*/
tcgetattr(fileno(stdin), &old_flags);
new_flags = old_flags;
/* Apagar l'echo local */
new_flags.c_lflag &= ~ECHO;
new_flags.c_lflag |= ECHONL;
/*Provar el funcionament */
retval = tcsetattr(fileno(stdin), TCSAFLUSH, &new_flags);
if(retval != 0)
err_quit("Error al canviar els atributs", old_flags);
/* S'ha modificat la configuració? */
tcgetattr(fileno(stdin), &new_flags);
if(new_flags.c_lflag & ECHO)
err_quit("Error al desconectar echo local", old_flags);
if(!new_flags.c_lflag & ECHONL)
err_quit("Error al conectar echo en una línia nova", old_flags);
fprintf(stdout, "Introdueix la contrasenya (atenció no introduiu una contrasenya important): ");
fgets(password, PASS_LEN + 1, stdin);
fprintf(stdout, "La teva contrasenya és : %s\n", password);
/* Restaurar la configuració anterior de termios*/
tcsetattr(fileno(stdin), TCSANOW, &old_flags);
exit(EXIT_SUCCESS);
}
void err_quit(char *msg, struct termios flags)
{
fprintf(stderr, "%s\n", msg);
tcsetattr(fileno(stdin), TCSANOW, &flags);
exit(EXIT_FAILURE);
}
Programació de terminals. terminfo
Així com termios permet controlar a un nivell molt baix els terminals, terminfo ens proporciona un nivell de control similar sobre el processament de la sortida. Permet operacions com netejar la terminal, posicionar el cursor o esborrar línies de caràcters.
Degut a la varietat de terminals existents, el dissenyadors de UNIX van aprendre a centralitzar les descripcions de les capacitats dels terminals en fitxers centralitzats. La paraula terminfo es refereix tant a la base de dades com a les rutines que tenim per accedir a aquesta base de dades.
NOTA: Cal fer notar que les bases de dades termcap (terminal capabilities) utilitzades a BSD són les antecesores de terminfo que van ser substituides per terminfo als sistemes System-V.
L'ordre en que és busca la base de dades terminfo és:
/etc/terminfo /lib/terminfo /usr/share/terminfo
Els fitxers d'aquestes carpetes són proporcionats en Debian pel paquet:
ncurses-base
Tal i com podem observar si executem:
$ dpkg -S /etc/terminfo ncurses-base
Recursos:
- man 5 terminfo
- man 5 termcap
- http://tldp.org/HOWTO/Text-Terminal-HOWTO-16.html
- Termcap/Terminfo Resources Page
- The Termcap manual by Richard Stallman
Exemples terminfo
Veiem un quants exemples amb la comanda tput:
- Reiniciar la terminal. Equivalent a la comanda reset:
$ tput reset
- Moure el cursor. Movem el cursor a l'inici de la línia
$ tput cup 0 0
O a la columna 4 i fila 20:
$ tput cup 20 4
- Netejar la finestra: Equivalent a la comanda Equivalent a la comanda clear.
$ tput clear
- Mostrant el número de columnes:
$ tput cols
- Mostrant el nom llarg de la terminal:
$ tput longname X11 terminal emulator
Recursos:
Rutines de baix nivell en C
#include <curses.h> #include <term.h> int setupterm(char *term, int fildes, int *errret); int setterm(char *term); TERMINAL *set_curterm(TERMINAL *nterm); int del_curterm(TERMINAL *oterm); int restartterm(const char *term, int fildes, int *errret); char *tparm(char *str, ...); int tputs(const char *str, int affcnt, int (*putc)(int)); int putp(const char *str); int vidputs(chtype attrs, int (*putc)(int)); int vidattr(chtype attrs); int vid_puts(attr_t attrs, short pair, void *opts, int (*putc) (char)); int vid_attr(attr_t attrs, short pair, void *opts); int mvcur(int oldrow, int oldcol, int newrow, int newcol); int tigetflag(char *capname); int tigetnum(char *capname); char *tigetstr(char *capname);
Exemple. Comanda clear amb c
El següent exemple esta extret i adaptat del codi font de la comanda clear:
/*
* clear.c -- clears the terminal's screen
*/
#include <curses.h>
#include <term.h>
#include <stdio.h>
#include <stdlib.h>
static int putch(int c) {
return putchar(c);
}
int main(int argc, char *argv) {
setupterm((char *) 0, 2, (int *) 0);
return (tputs(clear_screen, lines > 0 ? lines : 1, putch) == ERR) ? -1 : 0;
}
Ncurses
Ncurses és una llibreria de programació que proveeix una API per escriure aplicacions amb interfícies basades en text. Ncurses significa "new curses", ja que és un reemplaçament de la llibreria curses de BSD. Hi han APIS oficials per C, C++ i Ada però també es poden trobar per altres llenguatges com Perl, Ruby o PHP. Forma part del projecte GNU però és un dels pocs projectes que no es distribueix sota llicència GPL. Utilitza la llicència MIT.
Recursos:
Instal·lació
$ sudo apt-get install libncurses5 libncurses5-dev
Per 64 bits les llibreries són:
$ sudo apt-get install lib64ncurses5 lib64ncurses5-dev
També hi ha llibreries de ncurses per altres llenguatges de programació com Perl o Ruby.
Exemple HolaMon
Codi font:
- SVN:
svn checkout https://svn.lafarga.cpl.upc.edu/dades/svn/plinux/sessio6/ncurses
Veiem un primer exemple senzill de ncurses. El típic HolaMon!:
#include <ncurses.h>
int main() {
initscr();
printw("Hola Mon!!!");
refresh();
getch();
endwin();
return 0;
}
Per compilar codi font c amb llibreries em d'utilitzar el paràmetre :
$ gcc -o holamon -lncurses holamon.c
Exemple Finestra amb colors
Codi font:
$ svn checkout https://svn.lafarga.cpl.upc.edu/dades/svn/plinux/sessio6/ncurses
Ara afegim una mica de color a l'exemple anterior:
#include <ncurses.h>
int main() {
initscr();
if (has_colors()) {
start_color();
init_pair(1,COLOR_BLUE,COLOR_YELLOW); attron(COLOR_PAIR(1)); printw("Hola Mon!!!"); attroff(COLOR_PAIR(1));
}
refresh();
getch();
endwin();
return 0;
}
Per compilar codi font c amb llibreries em d'utilitzar el paràmetre :
$ gcc -o finestraambcolors -lncurses finestraambcolors.c
Dialog
Dialog és un conjunt d'utilitats que fent ús de ncurses facilita la creació de formulari amb l'usuari. Per instal·lar Dialog hem d'executar:
$ sudo apt-get install dialog
Veiem un exemple:
$ nom=$(dialog --stdout --inputbox "Digues el teu nom" 10 30)
Imatge:DebconfDialog1.png
Si ara executem
$echo "$nom"
Ens mostrarà el nom que hem introduït.
Dialog (NOTA: o potser una adaptació, no estic segur) es utilitzat per Debconf tal i com podeu veure en mes detall a l'article Creació de paquets Debian.
Recursos:
Zenity
Permet mostrar diàlegs de GTK (Gnome)
$ zenity --warning --text "This will kill, are you sure?";echo $?
Un diàleg de text:
$ szAnswer=$(zenity --entry --text "where are you?" --entry-text "at home"); echo $szAnswer
Escull un fitxer
Recursos:
- http://fosswire.com/2007/12/23/gtk-dialog-boxes-from-shell-scripts/
- http://linux.byexamples.com/archives/259/a-complete-zenity-dialog-examples-1/
- http://linux.byexamples.com/archives/265/a-complete-zenity-dialog-examples-2/
KDialog
Similar a l'anterior (zenity) però per a KDE:
$ kdialog --title FOSSwire --msgbox "FOSSwire is awesome"
Recursos:


