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

De SergiTurWiki
Share/Save/Bookmark
(S'ha redirigit des de: Emulador de terminal)
Dreceres ràpides: navegació, cerca
Alert.png Aquesta wiki forma part dels materials d'un curs
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:

Asr33.jpg

Després van vindre els terminals de vídeo amb suport només per a text:

Televideo925Terminal.jpg

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:

TerminalsRemots.png

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

TipusFitxersUnix.png

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:

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:

KDialog

Similar a l'anterior (zenity) però per a KDE:

$ kdialog --title FOSSwire --msgbox "FOSSwire is awesome"

Recursos:

Vegeu també