Redirectarile sunt principalul mijloc prin care stocam pe disc, in fisiere, prelucrarile de date facute de scripturi si programe.
Redirectare stdout
(standard output, în general mesaje afișate prin comenzi similare cu printf
din C). De exemplu, într-un sistem în care avem multe procese, e greu sa urmărim direct în consolă output-ul comenzii ps
:
training@box:~$ ps -f -u student > stdout.txt training@box:~$ cat stdout.txt
Putem redirecta doar mesajele de eroare către un fișier. Scenariu: Vrem să găsim toate fișierele cu extensia *.conf
din directorul /etc
.
training@box:~$ find /etc -name '*.conf' (...) find: `/etc/ppp/peers': Permission denied (...)
Ne deranjează mesajele de eroare din cauza lipsei drepturilor de citire asupra unor fișiere sau directoare. Pentru aceasta vom folosi:
training@box:~$ find /etc -name '*.conf' 2> errors.txt training@box:~$ cat errors.txt
Putem face combinații acum: redirectăm erorile într-un fișier și rezultatele în alt fișier:
training@box:~$ find /etc -name '*.conf' 2> errors.txt > stdout.txt
În cazul în care dorim să redirecționăm toate mesajele afișate de o comandă, la grămadă, folosim operatorul &>
:
training@box:~$ find /etc -name '*.conf' &> find_output.txt
procfs
, montat în /proc
. Pentru fiecare proces identificat printr-un PID, aveam directorul /proc/19827/fd
, care conținea link-uri simbolice către fișierele deschise de acel proces. Pentru fiecare proces în acel director găseam 0, 1, 2
. Acestea reprezintă respectiv:
0
- intrarea standard (stdin). Exemplu: tastatura1
- ieșirea standard (stdout). Exemplu: mesaje afișate cu printf
de un program C2
- ieșirea standard de eroare (stderr), unde se duc mesaje precum cele afișate de find mai sus.
Putem redirecta outputul și către device-uri virtuale, cum ar fi /dev/null
. În general facem acest lucru deoarece vrem să executăm o anumită comandă (într-un program sau într-un script), fără a ne interesa outputul ei. Pentru exemplul cu find
de mai sus, să zicem că dorim să ignorăm erorile:
training@box:~$ find /etc -name '*.conf' 2> /dev/null
2>
, &>
, >
trunchiază conținutul fișierului, dacă acesta exista. Ca alternativă aveam append mode, care se poate aplica și aici, fără probleme, astfel: 2>>
, &>>
, >>
.
Putem folosi lsof
pentru a verifica modul în care redirectarea afectează descriptorii unui proces.
Într-un tab de terminal porniți un proces sleep
folosind comanda: sleep 100
.
În alt tab, pentru a investiga descriptorii procesului sleep folosim comanda lsof -p $(pidof sleep)
.
Observăm că descriptorii standard referă terminalul în care a fost rulată comanda, moșteniți de la terminalul din shell-ul folosit.
Acum să invesigăm procesul sleep cu redictări în diverse fișiere. Folosiți comanda sleep 100 < /dev/zero > /dev/null 2> error.txt
Folosim comanda lsof anterioară pentru a investiga descriptorii procesului sleep. Putem observa unde pointează descriptorii standard de fișier pentru procesul pornit.
De multe ori dorim să căutăm într-o ierarhie de fișiere și directoare, dar după anumite criterii. Comanda cea mai potrivită în acest caz este find
. Folosiți find
pentru a afișa toate fișierele din ierarhia /etc/
(adică toate fișierele din /etc/, din subdirectoarele acestuia, din subdirectoarele subdirectoarelor etc.). Hint: Folosiți opțiunea -type
a comenzii find.
Extindeți comanda anterioară pentru a afișa toate fișierele din ierarhia /etc/
al căror nume începe cu litere între a și d. Hint: Folosiți opțiunea -name
a comenzii find și construcția [a-d]*
pentru a indica un șir care începe cu o literă între a și d urmată de orice altceva.
Extindeți comanda anterioară pentru a afișa toate fișierele din ierahia /etc/
care au permisiunile de forma rw-------
, adică 600. Hint: Folosiți opțiunea -perm
urmată de permisiunile căutate în format octal.
Pentru comanda finală, redirectați outputul în fișierul ~/file_list.txt
și erorile în ~/errors.txt
.
Schimbați directorul curent în directorul /home/training. Folosiți comanda echo
pentru a afișa pe ecran textul al doilea exercițiu
. Redirectați acest text într-un fișier numit ex2.txt
.
Folosiți comanda echo pentru a adăuga textul e mai lung decat primul
în fișierul ex2.txt
, fără a șterge conținutul său.
Scriind comanda gcc fără niciun parametru, veți primi un mesaj de eroare. Redirectați acest mesaj de eroare folosind un operator de redirectare într-un fişier numit gcc_error.txt
. Afișați conținutul fișierului pentru a confirma.
Redirectați ieșirea standard a comenzii strace -e open ls /lib
în fișierul strace.out
.
Redirectați ieșirea de eroare standard a comenzii strace -e open ls /lib
în fișierul strace.err
.
Redirectați atât ieșirea standard cât și ieșirea de eroare standard a comenzii strace -e open ls /lib
în fișierul strace.both
.
Filtrați (folosind grep libc
) ieșirea standard a comenzii strace -e open ls /lib
și apoi redirectați-o în strace-new.out
iar ieșirea de eroare standard în strace-new.err
.
Filtrați (folosind grep proc
) ieșirea de eroare standard a comenzii strace -e open ls /lib
și apoi redirectați-o în strace-newer.err
iar ieșirea standard în /dev/null
.
Adăugați output-ul generat la ieșirea de eroare standard și ieșirea standard a comenzii strace -e open ls /lib
în fișierul strace.log
. O nouă rulare a comenzii va conduce la adăugarea de informații la sfârșitul acestui fișier.
Folosiți utilitarul tee
atât pentru a afișa la ieșirea standard cât și a scrie în fișierul free.txt
ieșirea comenzii free
. Scrierea în fișier trebuie făcută fără a suprascrie ce era deja scris. (Hint: man tee
, append)
Explicați diferența de comportament între următoarele două comenzi:
cat / 2>&1 > error.txt cat / > error.txt 2>&1