divendres, 29 de maig de 2015

Bash I/O Redirections

Introducció:

L'objectiu d'aquest article es ajudar a comprendre com funcionen les redireccions d'entrada/eixida en bash i com es poden utilitzar amb bash. Si disposem de la versio 4.0 o posterior de bash, amb la següent comanda podem veure els descriptor de Linux associats a un pseudoterminal virtual /dev/pts/13.
lsof +f g -ap $BASHPID -d 0,1,2
COMMAND   PID USER   FD   TYPE FILE-FLAG DEVICE SIZE/OFF NODE NAME
bash    12135 root    0u   CHR     RW,LG 136,13      0t0   16 /dev/pts/13
bash    12135 root    1u   CHR     RW,LG 136,13      0t0   16 /dev/pts/13
bash    12135 root    2u   CHR     RW,LG 136,13      0t0   16 /dev/pts/13
Ací teniu un diagrama de com funciona un pseudoterminal en linux. La funció d'aquest article no es aprofundir sobre aquesta matèria sino ajudar a entendre millor el mecanisme.

El descriptors amb linux tenim el 0 per a l'entrada estandar, l'1 per a la eixida estandar i el 2 per a l'eixida d'errors. Quan es realitza un forc del process els descriptors s'hereden.
                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/13           |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| /dev/pts/13           |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/13           |
                  ---       +-----------------------+

Redirigint l'eixida estandar

Les redireccions de entrada/eixida ens permeten redirigir la eixida estandar a un altre fitxer diferent de la pantalla. En el seguüent cas utilitzant l'operador ">" redirigim l'eixida estandar d'un programa a un fitxer de text.
ls -l / > output.txt
En aquest cas la distribucio dels descriptors queda com segueix
                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/13           |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| output.txt            |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| /dev/pts/13           |
                  ---       +-----------------------+
Per defecte l'operador de redirecció rescriu el fitxer desde l'inici. Açò es pot utilitzar per buidar un fitxer.
> output.txt
Si la nostra intencio es afegir mes informació a un fitxer utilitzem el doble operador ">>" per afegir la informació al final del fitxer anterior.
ls -l /etc >> output.txt
Si provoquem un error i redirigim l'eixida estandar a un fitxer no aconseguirem res ja que els errors utilitzen l'eixida d'errors que explicarem en el següent apartat.
ls -l /donotexist > output.txt
ls: cannot access /donotexist: No such file or directory

Redirigint l'eixida d'error

Per a redirigir errors hem de redirigir el discriptor numero 2 a un fitxer. La manera de realitzar-ho es com segueix:
ls -l /donotexists 2> error.txt
En aquest cas la distribucio dels descriptors queda com segueix:
                  ---       +-----------------------+
standard input   ( 0 ) ---->| /dev/pts/13           |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard output  ( 1 ) ---->| /dev/pts/13           |
                  ---       +-----------------------+

                  ---       +-----------------------+
standard error   ( 2 ) ---->| error.txt             |
                  ---       +-----------------------+

Redirigit l'eixida estandar i l'eixida d'error

Per a realitzar la redirecció d'ambdós descriptor s'ha realitzat tradicionalment de la següent manera.
ls -l / > output.txt 2>&1
En aquest cas la distribucio dels descriptors queda com segueix:
                  ---        +-----------------------+
standard input   ( 0 ) ----->| /dev/pts/13           |
                  ---        +-----------------------+

                  ---        +-----------------------+
standard output  ( 1 ) ----->| output.txt            |
                  ---        +-----------------------+
                         
                  ---        +-----------------------+
standard error   ( 2 ) ----->| output.txt            |
                  ---        +-----------------------+
L'ordre es important, si ens equivoquem amb l'ordre
ls -l / 2>&1 > output.txt
El que provocarem es que l'eixida d'error segueixca vinculada a la pantalla, ja que quan copiarem el descriptor d'error amb el valor del descriptor d'eixida aquest encara tenia el valor inicial del terminal.
                  ---        +-----------------------+
standard input   ( 0 ) ----->| /dev/pts/13           |
                  ---        +-----------------------+

                  ---        +-----------------------+
standard output  ( 1 ) ----->| output.txt            |
                  ---        +-----------------------+
                         
                  ---        +-----------------------+
standard error   ( 2 ) ----->| /dev/pts/13           |
                  ---        +-----------------------+
En versions més actuals de bash, existeix l'abreviatura &>. Aquesta es una forma mes fàcil i comoda de realitzar la redireccio de l'entrada estandar i l'eixida a un mateix fitxer.
ls -l / &> output.txt
També podem utilitzar l'operador per a afegir com anteriorment.
ls -l / &>> output.txt

Enllaços

http://wiki.bash-hackers.org/howto/redirection_tutorial
http://sourceforge.net/projects/linuxcommand/files/TLCL/13.07/TLCL-13.07.pdf/download
http://en.wikipedia.org/wiki/Pseudoterminal

Cap comentari:

Publica un comentari a l'entrada