Redirecționarea fluxurilor I/O c. Programe canale și fluxuri, redirecționare

1403

Redirecționarea „2>&1”, „>/dev/null” sau a fluxurilor de ieșire pe Unix (bash/sh)

Evaluarea dvs.: capodopera minunat foarte bine bine normal Nu am citit tolerabil mediocru rău foarte rău nu citi

Fluxuri de ieșire

Mesajele script sunt transmise în fluxuri bine definite - fluxuri de ieșire. Deci prin ce ieșim

echo "Bună, lume!"

Nu este afișat doar pe ecran, ci, din punct de vedere al sistemului, și în special al interpretărilor de comenzi sh și bash, este scos printr-un flux de ieșire specific. În cazul ecou, ​​fluxul numărul 1 (stdout) cu care este asociat ecranul.

Unele programe și scripturi folosesc, de asemenea, un flux de ieșire diferit - numărul 2 (stderr). Acolo afișează mesaje de eroare. Acest lucru face posibilă separarea informațiilor obișnuite și a mesajelor de eroare din fluxuri și direcționarea și procesarea lor separat.

De exemplu, puteți bloca ieșirea mesaje informative, lăsând doar mesaje de eroare. Sau trimiteți mesaje de eroare către dosar separat pentru exploatare forestieră.

Ce este „>un fișier”

O astfel de intrare în Unix (în bash interprețiși sh) specifică redirecționarea fluxurilor de ieșire.

În exemplul următor, vom redirecționa toate mesajele informaționale (obișnuite) ale comenzii ls către fișierul myfile.txt, având astfel doar o listă de ls în acest fișier:

$ ls > fișierul meu.txt


În acest caz, după apăsarea Enter, nu veți vedea nimic pe ecran, dar fișierul myfile.txt va conține tot ceea ce ar fi trebuit să fie afișat pe ecran.

Cu toate acestea, haideți să facem o operațiune în mod deliberat eronată:

$ ls /masdfasdf > fișierul meu.txt


Deci ce se va întâmpla? Deoarece directorul masdfasdf nu există în rădăcina sistemului de fișiere (presupun că da - ce dacă faci?), atunci comanda ls va genera o eroare. Cu toate acestea, aceasta va arunca această eroare nu prin fluxul standard stdout (1), ci prin fluxul de erori stderr (2). Și redirecționarea este setată numai pentru stdout ("> myfile.txt").

Deoarece nu am redirecționat fluxul stderr(2) nicăieri - mesajul de eroare va apărea pe ecran și NU va apărea în fișierul myfile.txt

Acum haideți să rulăm comanda ls, astfel încât datele informațiilor să fie scrise în fișierul myfile.txt și mesajele de eroare să fie scrise în fișierul myfile.err, fără să apară nimic pe ecran în timpul execuției:

$ ls >fișierul meu.txt 2>fișierul meu.err


Aici întâlnim pentru prima dată indicarea unui număr de flux ca redirecționare. Intrarea „2>myfile.err” indică faptul că fluxul numărul 2 (stderr) ar trebui redirecționat către fișierul myfile.err.

Desigur, putem direcționa ambele fluxuri către același fișier sau către același dispozitiv.

2>&1

Puteți găsi adesea o astfel de intrare în scripturi. Înseamnă: „Redirecționează fluxul numărul 2 către fluxul numărul 1” sau „Stream stderr - redirecționează prin fluxul stdout”. Acestea. Dirijam toate mesajele de eroare prin firul prin care sunt tipărite de obicei mesajele normale, fără eroare.

$ ls /asfasdf 2>&1


Iată un alt exemplu în care toate mesajele sunt redirecționate către fișierul myfile.txt:

$ ls /asfasdf >fișierul meu.txt 2>&1


În acest caz, toate mesajele, atât de eroare, cât și normale, vor fi scrise în myfile.txt, deoarece Mai întâi am redirecționat fluxul stdout către un fișier și apoi am indicat că erorile ar trebui să fie aruncate în stdout - în consecință, în fișierul myfile.txt

/dev/null

Cu toate acestea, uneori trebuie doar să ascundem toate mesajele - fără a le salva. Acestea. doar blocați ieșirea. În acest scop este folosit dispozitiv virtual/dev/null. În următorul exemplu, vom direcționa toate mesajele obișnuite din comanda ls către /dev/null:

$ ls > /dev/null


Nu vor fi afișate nimic altceva decât mesajele de eroare pe ecran. Și în exemplul următor, mesajele de eroare vor fi blocate:

$ ls > /dev/null 2>&1


Mai mult, această înregistrare este echivalentă cu o înregistrare de forma:

$ ls >>/dev/null 2>/dev/null


Și în exemplul următor vom bloca doar mesajele de eroare:

$ ls 2>/dev/null

Vă rugăm să rețineți că nu mai puteți specifica aici „2>&1”, deoarece fluxul (1) nu este redirecționat nicăieri și, în acest caz, mesajele de eroare vor apărea pur și simplu pe ecran.

Ce este mai întâi - oul sau puiul?

Vă voi da aici 2 exemple.

Exemplul 1)

$ ls >>/dev/null 2>&1


Exemplul 2)

$ ls 2>&1 >/dev/null


În aparență, suma nu se schimbă prin rearanjarea locurilor silabelor. Dar ordinea indicatoarelor de redirecționare contează!

Ideea este că interpreții citesc și aplică redirecționări de la stânga la dreapta. Și acum ne vom uita la ambele exemple.

Exemplul 1

1) „>/dev/null” - direcționăm fluxul 1 (stdout) către /dev/null. Toate mesajele care intră în fluxul (1) vor fi trimise la /dev/null.

2) „2>&1” - redirecționăm fluxul 2 (stderr) către fluxul 1 (stdout). Dar, pentru că Firul 1 este deja asociat cu /dev/null - toate mesajele vor ajunge în continuare în /dev/null.

Rezultat: ecranul este gol.

Exemplul 2

1) „2>&1” - redirecționăm fluxul de erori stderr (2) către fluxul stdout (1). În același timp, pentru că firul 1 este asociat implicit terminalului - vom vedea cu succes mesaje de eroare pe ecran.

2) „>/dev/null” - și aici redirecționăm firul 1 către /dev/null. ȘI mesaje regulate nu vom vedea.

Rezultat: Vom vedea mesaje de eroare pe ecran, dar nu vom vedea mesaje normale.

Concluzie: redirecționează mai întâi fluxul, apoi leagă la el.

În sistem, în mod implicit, trei „fișiere” sunt întotdeauna deschise - (tastatură), (ecran) și (afișarea mesajelor de eroare pe ecran). Acestea și orice alte fișiere deschise pot fi redirecționate. ÎN în acest caz,, termenul „redirecționare” înseamnă a prelua rezultatul dintr-un fișier, comandă, program, script sau chiar un singur bloc dintr-un script (vezi Exemplul 3-1 și Exemplul 3-2) și îl transmiteți ca intrare într-un alt fișier, comandă, program sau script.

Fiecare fișier deschis are asociat un descriptor de fișier. Descriptorii de fișier și sunt 0, 1 și, respectiv, 2. La deschidere fișiere suplimentare, descriptorii de la 3 la 9 rămân neocupați. Uneori, descriptori suplimentari pot face o treabă bună în stocarea temporară a unui link către sau. Acest lucru facilitează readucerea mânerelor la starea lor normală după redirecționări complexe și manipulări de schimb (vezi Exemplul 16-1).

COMMAND_OUTPUT > # Se redirecționează stdout(ieșire) într-un fișier. # Dacă fișierul lipsea, acesta va fi creat, altfel va fi suprascris. ls -lR > dir-tree.list # Creează un fișier care conține o listă a unui arbore de directoare. : > nume de fișier # Operația > trunchiază fișierul „nume de fișier” la lungimea zero. # Dacă fișierul nu a existat înainte de operație, # este creat fișier nou Cu lungime zero(comanda „touch” are același efect). # Simbolul: acţionează ca substituent aici, fără a scoate nimic. > nume de fișier # Operația > trunchiază fișierul „nume fișier” la lungimea zero. # Dacă fișierul nu a existat înainte de operație, # atunci este creat un fișier nou cu lungime zero (comanda „touch” are același efect). # (același rezultat ca „:>” de mai sus, dar această opțiune nu funcționează # în unele shell-uri.) COMMAND_OUTPUT >> # Redirecționează stdout (ieșire) către un fișier. # Creează un fișier nou dacă lipsea, în caz contrar îl adaugă la sfârșitul fișierului. # Comenzi de redirecționare pe o singură linie # (afectează doar linia pe care apar): # ——————————————————————— 1>nume fișier # Redirecționare ieșire (stdout ) la fișierul „nume fișier”. 1>>filename # Redirecționează ieșirea (stdout) către fișierul „filename”, fișierul este deschis în modul anexare. 2>filename # Redirecționați stderr către fișierul „filename”. 2>>filename # Redirecționează stderr către fișierul „filename”, fișierul este deschis în modul anexare. &>filename # Redirecționează stdout și stderr către fișierul „filename”. #=================================================== === ============================= # Redirect stdout, doar pentru o linie. LOGFILE=script.log echo "Această linie va fi scrisă în fișierul \"$LOGFILE\"." 1>$LOGFILE echo "Această linie va fi adăugată la sfârșitul fișierului \"$LOGFILE\"." 1>>$LOGFILE echo "Această linie va fi adăugată și la sfârșitul fișierului \"$LOGFILE\"." 1>>$LOGFILE echo "Această linie va fi imprimată pe ecran și nu va ajunge în fișierul \"$LOGFILE\"." # După fiecare linie, redirecționarea efectuată este resetată automat. # Redirect stderr, doar pentru o linie. ERRORFILE=script.errors bad_command1 2>$ERRORFILE # Mesajul de eroare va fi scris în $ERRORFILE. bad_command2 2>>$ERRORFILE # Un mesaj de eroare va fi adăugat la sfârșitul $ERRORFILE. bad_command3 # Mesajul de eroare va fi tipărit în stderr, #+ și nu va merge la $ERRORFILE. # După fiecare linie, redirecționarea efectuată este de asemenea resetată automat. #=================================================== === ============================== 2>&1 # Redirecţionează stderr către stdout. # Mesajele de eroare sunt trimise în același loc ca ieșirea standard. i> i V j. # Ieșire în fișier cu descriptor i transmis în fișierul cu descriptor j. >&j # Descriptorul fișierului este redirecționat 1 (stdout) într-un fișier cu un descriptor j. # Ieșirea către stdout este trimisă la descriptorul fișierului j. 0< FILENAME < FILENAME # Ввод из файла. # Парная команде ">", adesea găsit în combinație cu acesta. # # grep search-word filename # Fișierul „filename” este deschis pentru citire și scriere și asociat cu mânerul „j”. # Dacă „nume fișier” lipsește, acesta este creat. # Dacă descriptorul „j” nu este specificat, atunci descriptorul 0, stdin, este luat în mod implicit. # # O utilizare pentru aceasta este de a scrie într-o anumită poziție dintr-un fișier. echo 1234567890 > Fișier # Scrieți un șir în fișierul „Fișier”. executiv 3<>Fișier # Deschideți „Fișier” și asociați-l cu mânerul 3. citiți -n 4<&3 # Прочитать 4 символа. echo -n . >&3 # Scrieți caracterul punct. exec 3>&- # Închideți mânerul 3. cat Fișier # ==> 1234.67890 # Acces aleatoriu, asta-i tot! | # Transportor (canal). # Remediu universal pentru a combina comenzile într-un singur lanț. # Arată ca „>”, dar este de fapt mai extins. # Folosit pentru a combina comenzi, scripturi, fișiere și programe într-un singur lanț (pipeline). pisica *.txt | sortare | uniq > rezultat-file # Conținutul tuturor fișierelor .txt este sortat, liniile duplicate sunt eliminate, # rezultatul este salvat în fișierul „result-file”.

Operațiunile de redirecționare și/sau conductele pot fi combinate pe aceeași linie de comandă.

comanda< input-file >comandă fișier de ieșire1 | comanda2 | command3 > output-file Vezi Exemplul 12-23 și Exemplul A-17.

Este posibil să redirecționați mai multe fluxuri către un singur fișier.

ls -yz >> command.log 2>&1 # Un mesaj despre o opțiune „yz” nevalidă din comanda „ls” va fi scris în fișierul „command.log”. # Deoarece stderr este redirecționat către un fișier.

Închiderea mânerelor fișierelor

Închideți descriptorul fișierului de intrare.

0<&-, <&-

Închideți descriptorul fișierului de ieșire.

1>&-, >&-

Procesele copil moștenesc mânere deschide fișiere. Acesta este motivul pentru care funcționează transportoarele. Pentru a preveni moștenirea mânerelor, închideți-le înainte de a începe procesul copil.

# Doar stderr este trecut în conductă. exec 3>&1 # Salvați „starea” curentă în stdout. ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Închide desc. 3 pentru „grep” (dar nu pentru „ls”). # ^^^^ ^^^^ exec 3>&- # Acum închideți-l pentru restul scriptului. # Mulțumesc S.C.

Pentru mai multe informații despre redirecționarea I/O, consultați Anexa D.

16.1. Folosind comanda exec

Echipă exec redirecționează intrarea de la către un fișier. De acum înainte, toate intrările, în loc de (de obicei, tastatura), se vor face din acest fișier. Acest lucru face posibilă citirea conținutului unui fișier, rând cu linie, și analizarea fiecărei linii introduse folosind sed și/sau awk.

Exemplul 16-1. Redirecționare cu exec

#!/bin/bash # Redirecționează stdin folosind „exec”. executiv 6<&0 # Связать дескр. #6 со стандартным вводом (stdin). # Сохраняя stdin. exec < data-file # stdin заменяется файлом "data-file" read a1 # Читается первая строка из "data-file". read a2 # Читается вторая строка из "data-file." echo echo "Следующие строки были прочитаны из файла." echo "——————————————" echo $a1 echo $a2 echo; echo; echo exec 0<&6 6<&- # Восстанавливается stdin из дескр. #6, где он был предварительно сохранен, #+ и дескр. #6 закрывается (6<&-) освобождая его для других процессов. # # <&6 6<&- дает тот же результат. echo -n "Введите строку " read b1 # Теперь функция "read", как и следовало ожидать, принимает данные с обычного stdin. echo "Строка, принятая со stdin." echo "—————————" echo "b1 = $b1" echo exit 0

La fel, designul exec >nume fișier redirecționează rezultatul către fișierul specificat. După aceasta, toate ieșirile din comenzile către care ar fi direcționate în mod normal sunt acum trimise în acest fișier.

Exemplul 16-2. Redirecționare cu exec

#!/bin/bash # reassign-stdout.sh LOGFILE=logfile.txt exec 6>&1 # Link desc. #6 cu stdout. # Stocarea stdout. exec > $LOGFILE # stdout este înlocuit cu fișierul „logfile.txt”. # ———————————————————— # # Toate ieșirile din comenzile din acest bloc sunt scrise în fișierul $LOGFILE. echo -n "Fișier jurnal: " date echo "————————————-" echo echo "Ieșire de \"ls -al\"" echo ls -al echo; echo echo "Ieșirea comenzii \"df\"" echo df # ———————————————————— # exec 1>&6 6>&- # Restaurați stdout și închideți fișierul. #6. echo echo "== stdout restaurat la implicit == " echo ls -al echo exit 0

Exemplul 16-3. Redirecționarea simultană a dispozitivelor și, folosind comanda exec

#!/bin/bash # upperconv.sh # Convertiți caracterele din fișierul de intrare în majuscule. E_FILE_ACCESS=70 E_WRONG_ARGS=71 dacă [ ! -r "$1" ] # Fișierul poate fi citit? apoi ecou „Imposibil de citit din cauza a acestui dosar!" echo "Utilizare: $0 fișier de intrare fișier de ieșire" exit $E_FILE_ACCESS fi # În cazul în care fișierul de intrare ($1) nu este specificat #+ codul de ieșire va fi același. dacă [ -z "$2" ] atunci echo " Trebuie specificat un fișier de ieșire echo "Utilizare: $0 fișier de intrare fișier de ieșire" exit $E_WRONG_ARGS fi exec 4<&0 exec < $1 # Назначить ввод из входного файла. exec 7>&1 exec > $2 # Atribui ieșirea unui fișier de ieșire. # Presupunând că fișierul de ieșire poate fi scris # (adăugați verificare?). # ———————————————— pisica — | tr a-z A-Z # Convertiți în majuscule # ^^^^^ # Citiți din stdin. # ^^^^^^^^^^ # Scrie la stdout. # Cu toate acestea, atât stdin cât și stdout au fost redirecționate. # ———————————————— exec 1>&7 7>&- # Restaurați stdout. exec 0<&4 4<&- # Восстановить stdin. # После восстановления, следующая строка выводится на stdout, чего и следовало ожидать. echo "Символы из \"$1\" преобразованы в верхний регистр, результат записан в \"$2\"." exit 0

Următorul: Redirecționarea erorilor către un fișier Sus: Redirecționare I/O Anterior: Redirecționarea intrării dintr-un fișier Cuprins Index

Redirecționarea ieșirii către un fișier

Pentru a redirecționa ieșirea standard către un fișier, utilizați operatorul `>'.

Redirecționare I/O în Linux

Urmați numele comenzii cu operatorul >, urmat de numele fișierului care va servi drept destinație pentru ieșire. De exemplu, pentru a scrie rezultatul unui program într-un fișier, introduceți:

Dacă redirecționați ieșirea standard către un fișier deja existent, acesta va fi suprascris de la început. Pentru a adăuga ieșirea standard la conținutul unui fișier existent, trebuie să utilizați operatorul `"'. De exemplu, pentru a adăuga rezultatele lucrării atunci când rulați din nou programul într-un fișier, introduceți:

Alex Otwagin 2002-12-16

Un program este de obicei valoros deoarece poate procesa date: acceptă un lucru, produce altul ca ieșire și aproape orice poate acționa ca date: text, numere, sunet, video... Fluxurile de date de intrare și de ieșire pentru o comandă sunt numite intrareȘi concluzie. Fiecare program poate avea mai multe fluxuri de intrare și de ieșire. În fiecare proces, atunci când este creat în obligatoriu primește așa-numita intrare standard(intrare standard, stdin) și ieșire standard(ieșire standard, stdout) și ieșire de eroare standard(eroare standard, stderr).

Fluxurile standard de intrare/ieșire sunt destinate în primul rând schimbului de informații text. Aici nici măcar nu contează cine comunică prin texte: o persoană cu un program sau programe între ei - principalul lucru este că are un canal de transmisie a datelor și că vorbește „aceeași limbă”.

Principiul textual al lucrului cu mașina vă permite să evadați din anumite părți ale computerului, cum ar fi tastatura sistemuluiși plăci video cu monitor, considerând un singur dispozitiv terminal, prin care utilizatorul introduce text (comenzi) și îl transmite sistemului, iar sistemul iese necesare utilizatorului date și mesaje (diagnostice și erori). Un astfel de dispozitiv este numit Terminal. ÎN caz general terminalul este punctul de intrare al utilizatorului în sistem și are capacitatea de a transmite informații text. Terminalul poate fi separat dispozitiv extern, conectat la un computer printr-un port de date serial (în calculator personal se numește „port COM”). Un program (de exemplu, xterm sau ssh) poate funcționa și ca terminal (cu un anumit suport din partea sistemului). In cele din urma, console virtuale- de asemenea terminale, organizate doar programatic folosind dispozitive adecvate calculator modern.

Când lucrați la linia de comandă, intrarea standard a shell-ului este asociată cu tastatura, iar ieșirea standard și ieșirea de eroare sunt asociate cu ecranul monitorului (sau fereastra emulatorului terminalului). Să arătăm cu un exemplu cea mai simplă comandă-pisică. De obicei echipa pisică citește datele din toate fișierele care sunt specificate ca parametrii săi și trimite citirea direct la ieșirea standard (stdout). Prin urmare comanda

/home/larry/papers# istoria pisicilor-teza-finală de master

va afișa mai întâi conținutul fișierului și apoi fișierul.

Cu toate acestea, dacă numele fișierului nu este specificat, programul pisică citește intrarea din stdin și o întoarce imediat la stdout (fără a o modifica în vreun fel). Datele trec prin pisică ca printr-o țeavă. Să dăm un exemplu:

/home/larry/papers# cat Bună ziua. Salutare. Pa. Pa. CtrlD/home/larry/papers#

Fiecare linie introdusă de la tastatură este imediat returnată pe ecran de către programul cat. La introducerea informațiilor din intrarea standard, sfârșitul textului este semnalat prin introducere combinație specială chei, de obicei CtrlD.

Să dăm un alt exemplu. Echipă fel citește linii de text de intrare (tot din stdin dacă nu este specificat niciun nume de fișier) și scoate un set de aceste linii într-o formă ordonată pe stdout. Să-i verificăm acțiunea.

/home/larry/papers# sort banane morcovi mere Ctrl+D mere banane morcovi /home/larry/papers#

După cum puteți vedea, după apăsare CtrlD, fel scoateți liniile ordonate în ordine alfabetică.

Intrare standard și ieșire standard

Să presupunem că doriți să direcționați ieșirea comenzi de sortareîntr-un fișier pentru a salva lista ordonată alfabetic pe disc. Shell-ul de comandă vă permite să redirecționați ieșirea standard a unei comenzi către un fișier folosind un simbol. Să dăm un exemplu:

/home/larry/papers# sort > lista de cumpărături banane morcovi mere CtrlD/home/larry/papers#

Puteți vedea că rezultatul comenzii sortare nu este imprimat pe ecran, dar este salvat într-un fișier numit. Să afișăm conținutul acestui fișier:

/home/larry/papers# lista de cumpărături pisică mere banane morcovi /home/larry/papers#

Acum lăsați lista originală neordonată să fie într-un fișier. Această listă poate fi sortată folosind comanda fel, spunându-i că ar trebui să citească dintr-un fișier dat, mai degrabă decât din intrarea lui standard și, în plus, redirecționând ieșirea standard către un fișier, așa cum sa făcut mai sus. Exemplu:

/home/larry/papers# sortare articole lista de cumpărături /home/larry/papers# listă de cumpărături pisică mere banane morcovi /home/larry/papers#

Cu toate acestea, puteți face acest lucru diferit redirecționând nu numai ieșirea standard, ci și intrare standard utilitare din fișier folosind simbolul:

/home/larry/papers# sort< items apples bananas carrots /home/larry/papers#

Rezultatul comenzii fel< items echivalent cu comanda sortați articolele, însă primul demonstrează următoarele: la emiterea comenzii fel< items sistemul se comportă ca și cum datele conținute în fișier ar fi fost introduse din intrare standard. Redirecționarea se face de către shell-ul de comandă. Echipă fel numele fișierului nu a fost raportat: această comandă a citit datele din intrarea ei standard ca și cum am fi introdus-o de la tastatură.

Să introducem conceptul filtru. Un filtru este un program care citește datele de la intrarea standard, le procesează într-un fel și trimite rezultatul la ieșirea standard. Când se aplică redirecționarea, fișierele pot fi utilizate ca intrare și ieșire standard. După cum sa menționat mai sus, în mod implicit, stdin și stdout se referă la tastatură și, respectiv, ecran. Programul de sortare este un filtru simplu - sortează datele de intrare și trimite rezultatul la ieșirea standard. Un filtru foarte simplu este programul pisică- nu face nimic cu datele de intrare, ci pur și simplu le trimite la ieșire.

Am demonstrat deja cum să folosiți programul de sortare ca filtru mai sus. Aceste exemple presupun că datele sursă se aflau într-un fișier sau că datele sursă vor fi introduse de la tastatură (input standard). Cu toate acestea, ce se întâmplă dacă doriți să sortați datele care sunt rezultatul unei alte comenzi, de exemplu, ls?

Vom sorta datele în ordine alfabetică inversă; acest lucru se realizează prin opțiunea de comandă fel. Dacă doriți să listați fișierele din directorul curent în ordine alfabetică inversă, o modalitate de a face acest lucru ar fi așa.

Redirecționare I/O

Să folosim mai întâi comanda ls:

/home/larry/papers# ls listă-în engleză-istorie-finale-note-teze de master /home/larry/papers#

Acum redirecționăm ieșirea comenzii lsîntr-un fișier numit file-list

/home/larry/papers# ls > lista de fișiere /home/larry/papers# sort -r lista de fișiere note masters-thesis history-final english-list /home/larry/papers#

Aici este rezultatul comenzii ls salvat într-un fișier, iar după aceea acest fișier a fost procesat de comandă fel. Cu toate acestea, această cale este neelegantă și necesită utilizarea fișier temporar pentru a stoca rezultatul programului ls.

O soluție la această situație ar putea fi crearea comenzi andocate(conducte). Andocarea este efectuată de shell-ul de comandă, care direcționează stdout-ul primei comenzi către stdin-ul celei de-a doua comenzi. În acest caz, dorim să trimitem comenzi către stdout ls la comenzile stdin fel. Un simbol este utilizat pentru andocare, așa cum se arată în exemplul următor:

/home/larry/papers# ls | sortare -r note teze de master istorie-finală listă-engleză /home/larry/papers#

Această comandă este mai scurtă decât o colecție de comenzi și este mai ușor de tastat.

Să luăm în considerare un altul exemplu util. Echipă

/home/larry/papers# ls /usr/bin

returnează o listă lungă de fișiere. Majoritatea acestei liste zboară pe ecran prea repede pentru ca conținutul acestei liste să poată fi citit. Să încercăm să folosim comanda more pentru a afișa această listă în părți:

/home/larry/papers# ls /usr/bin | Mai mult

Acum puteți „retoarce” această listă.

Puteți merge mai departe și puteți andoca mai mult de două echipe. Luați în considerare echipa cap, care este un filtru cu următoarea proprietate: scoate primele linii din fluxul de intrare (în cazul nostru, intrarea va fi ieșirea din mai multe comenzi concatenate). Dacă dorim să afișăm ultimul nume de fișier alfabetic în directorul curent, putem folosi următoarea comandă lungă:

/home/larry/papers# ls | sortare -r | cap -1 note /home/larry/papers\#

unde este echipa cap afișează prima linie a fluxului de intrare de linii pe care le primește (în cazul nostru, fluxul este format din date de la comandă ls), sortate în ordine alfabetică inversă.

Utilizarea comenzilor stivuite (pipeline)

Efectul utilizării unui simbol pentru a redirecționa fișierul de ieșire este distructiv; cu alte cuvinte, echipa

/home/larry/papers# ls > lista de fișiere

va distruge conținutul fișierului dacă fișierul a existat anterior și va crea un fișier nou în locul său.

Dacă redirecționarea se face folosind simboluri, rezultatul va fi atașat la sfârșitul fișierului specificat fără a distruge conținutul original al fișierului. De exemplu, comanda

/home/larry/papers# ls >> lista de fișiere

atribuie rezultatul comenzii ls până la sfârșitul dosarului.

Vă rugăm să rețineți că redirecționarea de intrare și ieșire și îmbinarea comenzilor sunt efectuate shell-uri de comandă, care sprijină utilizarea simbolurilor și. Echipele însele nu sunt capabile să perceapă și să interpreteze aceste simboluri.

Redirecționare nedistructivă a ieșirii

Ceva de genul acesta ar trebui să facă ceea ce aveți nevoie?

Verificați: Wintee

Nu este nevoie de cygwin.

Cu toate acestea, am întâlnit și am raportat unele probleme.

De asemenea, ați putea dori să verificați http://unxutils.sourceforge.net/ deoarece conține tee (și nu are nevoie de cygwin), dar aveți grijă ca ieșirea EOL să fie asemănătoare UNIX.

Nu în ultimul rând, dacă aveți PowerShell, puteți încerca Tee-Object. Introduceți consola PowerShell pentru mai multe informații.

Aceasta funcționează, deși este puțin urâtă:

Este puțin mai flexibil decât alte soluții, deoarece funcționează în felul său, astfel încât să îl puteți folosi pentru a adăuga.

Folosesc asta destul de mult în fișierele batch pentru a înregistra și afișa mesaje:

Da, puteți repeta pur și simplu declarația ECHO (o dată pentru ecran și a doua oară redirecționând la fișierul jurnal), dar asta arată la fel de rău și este o problemă de întreținere.

Redirecționarea intrării și ieșirii

Cel puțin astfel nu trebuie să faceți modificări mesajelor în două locuri.

Rețineți că _ este doar nume scurt fișier, așa că va trebui să-l eliminați la sfârșitul fișierului batch (dacă utilizați fișier batch).

Acest lucru va crea un fișier jurnal cu ora curentăși timp și puteți utiliza linii de consolă în timpul procesului

Dacă aveți cygwin în cale Mediul Windows, poți să folosești:

Simplu aplicație de consolă C# ar face truc:

Pentru a utiliza acest lucru, pur și simplu treceți comanda sursă programului și specificați calea către orice fișiere pentru care doriți să duplicați rezultatul. De exemplu:

Va afișa rezultatele căutării și, de asemenea, vor salva rezultatele în files1.txt și files2.txt.

Rețineți că nu există prea multe în ceea ce privește gestionarea erorilor (nimic!) și este posibil ca suportul pentru mai multe fișiere să nu fie necesar.

Și eu căutam aceeași soluție, după o mică încercare am reușit să fac asta cu succes pe linia de comandă. Iată soluția mea:

Deturnează chiar și orice comandă PAUSE.

O alternativă este să introduceți stdout în stderr în programul dvs.:

Apoi, în fișierul dos batch:

Stdout va merge la fișierul jurnal și stderr (aceleași date) va fi afișat pe consolă.

Cum să afișați și să redirecționați ieșirea către un fișier. Să presupunem că dacă folosesc dos comandă, dir> test.txt, această comandă redirecționează rezultatul către fișierul test.txt fără a afișa rezultatele. cum se scrie o comandă pentru a imprima rezultatul și a redirecționa rezultatul către un fișier cu folosind DOS, adică comanda șiruri de ferestre, nu UNIX/LINUX.

Puteți găsi aceste comenzi în biterscripting (http://www.biterscripting.com) utile.

Aceasta este o variație a răspunsului anterior al MTS, dar adaugă unele caracteristici care pot fi utile altora. Iată metoda pe care am folosit-o:

  • Comanda este setată ca o variabilă care poate fi utilizată mai târziu în cod pentru a fi scoasă în fereastra de comandă și adăugată la fișierul jurnal folosind
    • comanda evită redirecționarea folosind simbolul morcov, astfel încât comenzile să nu fie evaluate inițial
  • Un fișier temporar este creat cu un nume de fișier similar cu un fișier batch cu un nume care utilizează sintaxa extensiei parametrului Linie de comanda pentru a obține numele fișierului batch.
  • Rezultatul este adăugat într-un fișier jurnal separat

Iată secvența comenzilor:

  1. Mesajele de ieșire și de eroare sunt trimise într-un fișier temporar
  2. Conținutul fișierului temporar este atunci:
    • adăugat la fișierul jurnal
    • ieșire în fereastra de comandă
  3. Fișierul temporar cu mesajul este șters

Iată un exemplu:

În acest fel, comanda poate fi adăugată pur și simplu după comenzile ulterioare într-un fișier batch, care arată mult mai curat:

Acesta poate fi adăugat și la sfârșitul altor comenzi. Din câte îmi pot da seama, acest lucru va funcționa atunci când mesajele au mai multe linii. De exemplu, următoarea comandă imprimă două rânduri dacă există un mesaj de eroare:

Sunt de acord cu Brian Rasmussen, portul unxutils este cel mai simplu mod de a face asta. În secțiunea Fișiere lot a paginilor sale de Scripting, Rob van der Woude oferă o mulțime de informații despre utilizarea comenzilor MS-DOS și CMD. M-am gândit că ar putea avea propria solutie problema ta și după ce am săpat în TEE.BAT, am găsit TEE.BAT, care pare să fie doar atât, un lot pachet lingvistic MS-DOS. Acesta este un fișier batch destul de complex și aș fi înclinat să folosesc portul unxutils.

Instalez perl pe majoritatea mașinilor mele, așa că răspunsul este folosind perl: tee.pl

dir | perl tee.pl sau catalog | perl tee.pl dir.bat

brute și netestate.

Unul dintre cele mai interesante și utile subiecte pentru administratorii de sistemși utilizatori noi care abia încep să înțeleagă cum să lucreze cu terminalul - aceasta este redirecționarea fluxurilor de intrare/ieșire Linux. Această caracteristică de terminal vă permite să redirecționați ieșirea comenzilor către un fișier sau conținutul unui fișier către intrarea comenzilor, să combinați comenzile împreună și să formați conducte de comandă.

În acest articol ne vom uita la modul în care se realizează redirecționarea fluxului I/O în Linux, ce operatori sunt utilizați pentru aceasta și unde pot fi utilizate toate acestea.

Toate comenzile pe care le executăm ne returnează trei tipuri de date:

  • Rezultatul comenzii, de obicei date text solicitate de utilizator;
  • Mesaje de eroare - informează despre procesul de execuție a comenzii și circumstanțe neașteptate care au apărut;
  • Codul de returnare este un număr care vă permite să evaluați dacă programul a funcționat corect.

În Linux, toate substanțele sunt considerate fișiere, inclusiv fluxurile de intrare ieșire Linux- dosare. Fiecare distribuție are trei fișiere de flux principal pe care programele le pot folosi, acestea sunt definite de shell și identificate prin numărul descriptor al fișierului:

  • STDIN sau 0- acest fișier este asociat cu tastatura și majoritatea comenzilor primesc date pentru a funcționa de aici;
  • STDOUT sau 1- aceasta este ieșirea standard, programul trimite aici toate rezultatele muncii sale. Este conectat la ecran, sau mai precis, la terminalul în care rulează programul;
  • STDERR sau 2- toate mesajele de eroare sunt trimise în acest fișier.

Redirecționarea I/O vă permite să înlocuiți unul dintre aceste fișiere cu al dvs. De exemplu, puteți avea un program să citească date dintr-un fișier în Sistemul de fișiere, mai degrabă decât tastatura, puteți, de asemenea, să afișați erori într-un fișier și nu pe ecran, etc. Toate acestea se fac folosind simboluri "<" Și ">" .

Redirecționați rezultatul către fișier

Totul este foarte simplu. Puteți redirecționa ieșirea către un fișier folosind simbolul >. De exemplu, să salvăm rezultatul comenzii de sus:

top -bn 5 > top.log

Opțiunea -b face ca programul să ruleze în modul lot non-interactiv, iar n - repetă operația de cinci ori pentru a obține informații despre toate procesele. Acum să vedem ce s-a întâmplat cu pisica:

Simbol ">" suprascrie informații dintr-un fișier dacă există deja ceva acolo. Pentru a adăuga date la utilizarea finală ">>" . De exemplu, redirecționați ieșirea către fișier linux de asemenea pentru top:

top -bn 5 >> top.log

În mod implicit, descriptorul standard al fișierului de ieșire este utilizat pentru redirecționare. Dar puteți specifica acest lucru în mod explicit. Această comandă va da același rezultat:

top -bn 5 1>top.log

Redirecționați erorile către fișier

Pentru a redirecționa rezultatul erorii către un fișier, trebuie să specificați în mod explicit descriptorul de fișier pe care urmează să-l redirecționați. Pentru erori, acesta este numărul 2. De exemplu, când încercați să obțineți acces la directorul de superutilizator, ls va afișa o eroare:

Puteți redirecționa eroarea standard către un fișier ca acesta:

ls -l /root/ 2> ls-error.log
$ cat ls-error.log

Pentru a adăuga date la sfârșitul fișierului, utilizați același simbol:

ls -l /root/ 2>>ls-error.log

Redirecționați rezultatul standard și erorile către fișier

De asemenea, puteți redirecționa toate rezultatele, erorile și ieșirile standard către un singur fișier. Există două moduri de a face acest lucru. Primul, mai vechi, este să treci ambele mânere:

ls -l /root/ >ls-error.log 2>&1

Mai întâi, rezultatul comenzii ls va fi trimis în fișierul ls-error.log folosind primul caracter de redirecționare. Apoi toate erorile vor fi trimise în același fișier. A doua metodă este mai simplă:

ls -l /root/ &> ls-error.log

De asemenea, puteți utiliza adăugarea în loc de rescrie:

ls -l /root/ &>> ls-error.log

Intrare standard din fișier

Majoritatea programelor, cu excepția serviciilor, primesc date pentru activitatea lor prin intrare standard. În mod implicit, intrarea standard așteaptă intrare de la tastatură. Dar puteți forța programul să citească date dintr-un fișier folosind operatorul "<" :

pisică

De asemenea, puteți redirecționa imediat rezultatul către un fișier. De exemplu, să resortăm lista:

fel sortare.ieșire

Astfel, redirecționăm intrarea/ieșirea către Linux într-o singură comandă.

Utilizarea tunelurilor

Puteți lucra nu numai cu fișiere, ci și redirecționați ieșirea unei comenzi ca intrare a alteia. Acest lucru este foarte util pentru efectuarea de operațiuni complexe. De exemplu, să afișăm cinci fișiere modificate recent:

ls -lt | cap -n 5

Cu utilitarul xargs, puteți combina comenzi astfel încât intrarea standard să fie transmisă ca parametri. De exemplu, să copiem un fișier în mai multe foldere:

echo test/tmp/ | xargs -n 1 cp -v testfile.sh

Aici opțiunea -n 1 specifică că trebuie furnizat un singur parametru per comandă, iar opțiunea -v pentru cp permite tipărirea informațiilor detaliate despre mișcări. O altă comandă utilă în astfel de cazuri este tee-ul. Citește date de la intrarea standard și scrie în fișiere sau fișiere standard. De exemplu:

echo „Test de funcționare Tee” | dosar tee1

În combinație cu alte comenzi, acestea pot fi folosite pentru a crea instrucțiuni complexe cu mai multe comenzi.

concluzii

În acest articol, am acoperit elementele de bază ale redirecționării fluxului I/O Linux. Acum știți cum să redirecționați ieșirea către un fișier Linux sau ieșirea dintr-un fișier. Este foarte simplu și convenabil. Dacă aveți întrebări, întrebați în comentarii!

Capacitățile de redirecționare încorporate ale Linux vă oferă o gamă largă de instrumente simplificate pentru tot felul de sarcini. Capacitatea de a gestiona diverse fluxuri I/O va crește semnificativ productivitatea, atât la dezvoltarea unui software complex, cât și la gestionarea fișierelor folosind linia de comandă.

Fire I/O

Intrările și ieșirile într-un mediu Linux sunt distribuite între trei fire de execuție:

  • Intrare standard (intrare standard, stdin, numărul firului 0)
  • Ieșire standard (stdout, numărul 1)
  • Eroare standard sau flux de diagnosticare (eroare standard, stderr, numărul 2)

Când un utilizator interacționează cu un terminal, intrarea standard este transmisă prin tastatura utilizatorului. Ieșirea standard și eroarea standard sunt afișate ca text pe terminalul utilizatorului. Toate aceste trei fluxuri sunt numite fluxuri standard.

Intrare standard

Fluxul de intrare standard transmite de obicei date de la utilizator către program. Programele care așteaptă intrare standard primesc de obicei intrare de la un dispozitiv (cum ar fi o tastatură). Intrarea standard se oprește când ajunge la EOF (sfârșitul fișierului). EOF indică faptul că nu mai sunt date de citit.

Pentru a vedea cum funcționează intrarea standard, rulați programul cat. Numele acestui instrument înseamnă „concatenează” (a conecta sau combina ceva). De obicei, acest instrument este folosit pentru a combina conținutul a două fișiere. Când rulează fără argumente, cat deschide un prompt de comandă și acceptă conținutul intrării standard.

Acum introduceți câteva numere:

1
2
3
ctrl-d

Introducând un număr și apăsând enter, trimiteți o intrare standard către programul cat rulează, care acceptă datele. La rândul său, programul cat afișează intrarea primită pe ieșirea standard.

Utilizatorul poate seta EOF apăsând ctrl-d, ceea ce va determina oprirea programului cat.

Ieșire standard

Ieșirea standard înregistrează datele generate de program. Dacă ieșirea standard nu a fost redirecționată, va trimite text către terminal. Încercați să rulați următoarea comandă ca exemplu:

echo Trimis la terminal prin ieșire standard

Comanda echo, fără opțiuni suplimentare, afișează pe ecran toate argumentele transmise acesteia pe linia de comandă.

Acum rulați echo fără niciun argument:

Comanda va returna un șir gol.

Eroare standard

Acest flux standard înregistrează erori generate de un program care s-a prăbușit. La fel ca ieșirea standard, acest flux trimite date către terminal.

Să ne uităm la un exemplu de flux de erori de comandă ls. Comanda ls afișează conținutul directoarelor.

Fără argumente, această comandă returnează conținutul directorului curent. Dacă furnizați un nume de director ca argument pentru ls, comanda va returna conținutul său.

Deoarece directorul % nu există, comanda va returna eroarea standard:

ls: nu poate accesa %: Nu există un astfel de fișier sau director

Redirecționarea fluxului

Linux oferă comenzi speciale pentru a redirecționa fiecare fir. Aceste comenzi scriu rezultate standard într-un fișier. Dacă rezultatul este redirecționat către un fișier inexistent, comanda va crea un fișier nou cu acel nume și va salva rezultatul redirecționat în el.

Comenzile cu un parantez unghiular suprascriu conținutul existent al fișierului țintă:

  • > - ieșire standard
  • < — стандартный ввод
  • 2> - eroare standard

Comenzile cu paranteze unghiulare duble nu suprascriu conținutul fișierului țintă:

  • >> - ieșire standard
  • << — стандартный ввод
  • 2>> - eroare standard

Luați în considerare următorul exemplu:

pisică > scrie_către_mi.txt
A
b
c
ctrl-d

Acest exemplu folosește comanda cat pentru a scrie rezultatul într-un fișier.

Examinați conținutul write_to_me.txt:

cat write_to_me.txt

Comanda ar trebui să returneze:

Redirecționează cat la write_to_me.txt din nou și introduceți trei numere.

pisică > scrie_către_mi.txt
1
2
3
ctrl-d

Acum verificați conținutul fișierului.

cat write_to_me.txt

Comanda ar trebui să returneze:

După cum puteți vedea, fișierul conține doar cea mai recentă ieșire, deoarece comanda care a redirecționat ieșirea a folosit un singur parantez unghiular.

Acum încercați să rulați aceeași comandă cu două paranteze unghiulare:

pisică >> scrie_mie.txt
A
b
c
ctrl-d

Deschideți write_to_me.txt:

1
2
3
A
b
c

Comenzile cu paranteze unghiulare duble nu suprascriu conținutul existent, ci se adaugă acestuia.

Transportoare

Conductele redirecționează ieșirea unei comenzi către intrarea alteia. În acest caz, datele transferate în al doilea program nu sunt afișate în terminal. Datele vor apărea pe ecran numai după procesarea de către al doilea program.

Conductele în Linux sunt reprezentate de o bară verticală.

De exemplu:

Această comandă va transmite rezultatul ls (conținutul directorului curent) către less, care va afișa datele transmise linie cu linie. De obicei, ls afișează conținutul directoarelor consecutiv, fără a le împărți în rânduri. Dacă redirecționați ieșirea ls la less, ultima comandă va împărți ieșirea în linii.

După cum puteți vedea, o conductă poate redirecționa ieșirea unei comenzi către intrarea alteia, spre deosebire de > și >>, care redirecționează doar datele către fișiere.

Filtre

Filtrele sunt comenzi care pot modifica redirecționarea și ieșirea unei conducte.

Notă: Filtrele sunt, de asemenea, comenzi standard Linux care pot fi utilizate fără o conductă.

  • find – caută un fișier după nume.
  • grep – caută text folosind un model dat.
  • tee – redirecționează intrarea standard către ieșirea standard și unul sau mai multe fișiere.
  • tr – caută și înlocuiește șiruri.
  • wc – numărarea caracterelor, rândurilor și cuvintelor.

Exemple de redirecționare I/O

Acum că sunteți familiarizat cu conceptele și mecanismele de bază ale redirecționării, să ne uităm la câteva exemple de bază ale utilizării lor.

comandă > fișier

Acest model redirecționează rezultatul standard al comenzii către un fișier.

ls ~> root_dir_contents.txt

Această comandă transmite conținutul directorului rădăcină al sistemului ca ieșire standard și scrie rezultatul în fișierul root_dir_contents. Aceasta va șterge tot conținutul anterior din fișier, deoarece comanda folosește un singur parantez unghiular.

comandă > /dev/null

/dev/null este un fișier special (numit „dispozitiv nul”) care este folosit pentru a suprima ieșirea standard sau diagnosticarea pentru a evita ieșirea nedorită din consolă. Toate datele care ajung în /dev/null sunt eliminate. Redirecționarea către /dev/null este folosită în mod obișnuit în scripturile shell.

ls > /dev/null

Această comandă resetează ieșirea standard returnată de ls la /dev/null.

comanda 2 > fișier

Acest model redirecționează fluxul de erori standard al comenzii către un fișier, suprascriind conținutul său curent.

mkdir "" 2> mkdir_log.txt

Această comandă va redirecționa eroarea cauzată de un nume de director nevalid și o va scrie în log.txt. Vă rugăm să rețineți: eroarea apare în continuare în terminal.

comandă >> fișier

Acest model redirecționează ieșirea standard a comenzii către un fișier fără a suprascrie conținutul curent al fișierului.

echo Scris într-un fișier nou > data.txt
echo Adăugat la conținutul unui fișier existent >> data.txt

Această pereche de comenzi redirecționează mai întâi intrarea utilizatorului către un fișier nou și apoi îl lipește într-un fișier existent fără a-i suprascrie conținutul.

comanda 2>>fișier

Acest model redirecționează fluxul de erori standard al comenzii către un fișier fără a suprascrie conținutul existent al fișierului. Este potrivit pentru crearea jurnalelor de erori de program sau serviciu, deoarece conținutul jurnalului nu va fi actualizat în mod constant.

găsiți „” 2> stderr_log.txt
wc "" 2>> stderr_log.txt

Comanda de mai sus redirecționează mesajul de eroare cauzat de argumentul find invalid în fișierul stderr_log.txt și apoi adaugă mesajul de eroare cauzat de argumentul wc invalid la fișierul stderr_log.txt.

echipa | echipă

Acest șablon redirecționează ieșirea standard a primei comenzi către intrare standard echipa a doua.

găsi /var lib | grep deb

Această comandă caută în directorul /var și subdirectoarele sale nume de fișiere și extensii deb și returnează căile fișierelor, evidențiind modelul de căutare în roșu.

echipa | dosar tee

Acest model redirecționează ieșirea standard a comenzii către un fișier și suprascrie conținutul acestuia, apoi afișează rezultatul redirecționat în terminal. Dacă fișierul specificat nu există, acesta creează un fișier nou.

ÎN acest șablon Comanda tee este de obicei folosită pentru a vizualiza rezultatul unui program și pentru a-l salva într-un fișier în același timp.

wc /etc/magic | tee magic_count.txt

Această comandă transmite numărul de caractere, rânduri și cuvinte dosar magic(Linux folosește acest lucru pentru a determina tipurile de fișiere) la comanda tee, care trimite aceste date către terminal și către fișierul magic_count.txt.

echipa | echipa | comandă >> fișier

Acest șablon redirecționează ieșirea standard a primei comenzi și o filtrează prin următoarele două comenzi, apoi adaugă rezultatul final la un fișier.

ls ~ | grep *tar | tr e E >> ls_log.txt

Această comandă trimite rezultatul lui ls pentru directorul rădăcină la grep. La rândul său, grep caută datele primite fișiere tar. După aceasta, rezultatul grep este trecut la comanda tr, care va înlocui toate caracterele e cu caracterul E. Rezultatul rezultat va fi adăugat la fișierul ls_log.txt (dacă un astfel de fișier nu există, comanda va crea este automat).

Concluzie

Funcțiile de redirecționare Linux I/O par prea complexe la început. Cu toate acestea, lucrul cu redirecționarea este una dintre cele mai importante abilități ale unui administrator de sistem.

Pentru a afla mai multe despre o anumită comandă, utilizați:

man comandă | Mai puțin

De exemplu:

Această comandă va reveni lista plina comenzi pentru tee.

Etichete:

Învățarea Linux, 101

Fluxuri, canale de programe și redirecționări

Învățarea elementelor de bază ale conductelor Linux

Seria de conținut:

Scurtă recenzie

În acest articol, veți învăța tehnicile de bază pentru redirecționarea fluxurilor I/O standard în Linux. O sa inveti:

  • Redirecționați fluxurile de intrare/ieșire standard: intrare standard, ieșire standard și eroare standard.
  • Direcționați ieșirea unei comenzi către intrarea altei comenzi.
  • Trimite ieșire simultan către dispozitiv standard ieșire (stdout) și într-un fișier.
  • Utilizați rezultatul unei comenzi ca argumente pentru o altă comandă.

Acest articol vă va ajuta să vă pregătiți pentru a susține examenul de administrator LPI 101 nivel de intrare(LPIC-1) și conține materiale de la Obiectivul 103.4 al Subiectului 103. Obiectivul are o pondere de 4.

Despre acest serial

Această serie de articole vă va ajuta să vă ocupați de sarcinile de administrare sistem de operare Linux. Puteți folosi și materialul din aceste articole pentru a vă pregăti.

Pentru a vedea descrierile articolelor din această serie și pentru a obține link-uri către acestea, vă rugăm să consultați pagina noastră. Această listă este actualizată continuu cu articole noi pe măsură ce devin disponibile și conține cele mai actuale obiective ale examenului de certificare LPIC-1 (din aprilie 2009). Dacă lipsește vreun articol din listă, îl puteți găsi mai multe versiunea anterioară, în concordanță cu obiectivele LPIC-1 anterioare (înainte de aprilie 2009), făcând referire la .

Conditiile necesare

A extrage cel mai mare beneficiu din articolele noastre, trebuie să aveți cunoștințe de bază despre Linux și să aveți un computer Linux funcțional pe care să puteți executa toate comenzile pe care le întâlniți. Uneori versiuni diferite Programele produc rezultate diferit, astfel încât conținutul listelor și cifrelor pot diferi de ceea ce vedeți pe computer.

Pregătirea pentru a rula exemplele

Cum să-l contactezi pe Ian

Ian este unul dintre cei mai populari și prolifici autori ai noștri. Consultați (EN) publicat pe developerWorks. Puteți găsi informații de contact la și puteți intra în legătură cu el și cu alți colaboratori și colaboratori My developerWorks.

Pentru a rula exemplele din acest articol, vom folosi unele dintre fișierele create mai devreme în articolul " ". Dacă nu ați citit acest articol sau nu ați salvat aceste fișiere, nu vă faceți griji! Să începem prin a crea un nou director lpi103-4 și tot fisierele necesare. Pentru a face acest lucru, deschideți o fereastră de text și navigați la directorul dvs. de acasă. Copiați conținutul Lista 1 în caseta de text; ca urmare a executării comenzilor în dvs directorul principal Va fi creat subdirectorul lpi103-4 și toate fișierele necesare din acesta, pe care le vom folosi în exemplele noastre.

Listarea 1. Crearea fișierelor necesare pentru exemplele acestui articol
mkdir -p lpi103-4 && cd lpi103-4 && ( echo -e "1 măr\n2 pere\n3 banane" > text1 echo -e "9\tplum\n3\tbanana\n10\tapple" > text2 echo "Acesta este o propoziție " !#:* !#:1->text3 split -l 2 text1 split -b 17 text2 y; )

Fereastra ar trebui să arate ca Lista 2, iar directorul de lucru actual ar trebui să fie directorul nou creat lpi103-4.

Listarea 2. Rezultatele creării fișierelor necesare
$ mkdir -p lpi103-4 && cd lpi103-4 && ( > echo -e "1 măr\n2 pere\n3 banane" > text1 > echo -e "9\tplum\n3\tbanana\n10\tapple" > text2 > echo "Aceasta este o propoziție." !#:* !#:1->text3echo "Aceasta este o propoziție." -b 17 text2 y ) $

Redirecționarea intrării/ieșirii standard

Un shell Linux, cum ar fi Bash, primește intrare și trimite ieșiri sub formă de secvențe sau cursuri personaje. Orice caracter este independent de caracterele anterioare sau ulterioare. Simbolurile nu sunt organizate în intrări structurate sau blocuri de dimensiuni fixe. Fluxurile sunt accesate folosind mecanisme I/O, indiferent de unde provin sau sunt trimise fluxurile de caractere (un fișier, tastatură, fereastră, ecran sau alt dispozitiv I/O). Interpreți de comandă Linux folosește trei fluxuri I/O standard, fiecăruia fiind atribuit un anumit descriptor de fișier.

  1. stdoutieșire standard, afișează ieșirea comenzii și are mânerul 1.
  2. stderrfluxul de erori standard, afișează erori de comandă și are descriptorul 2.
  3. stdinintrare standard, trece intrarea la comenzi și are mânerul 0.

Fluxurile de intrare oferă intrare (de obicei de la tastatură) la comenzi. Fluxurile de ieșire asigură imprimarea caractere text, de obicei la terminal. Terminalul a fost inițial un dispozitiv de imprimare ASCII sau un terminal de afișare, dar acum este de obicei doar o fereastră pe desktopul computerului.

Dacă ați citit deja ghidul „”, atunci unele dintre materialele din acest articol vă vor fi familiare.

Redirecționarea ieșirii

Există două moduri de a redirecționa ieșirea către un fișier:

n> redirecționează ieșirea dintr-un descriptor de fișier n la dosar. Trebuie să aveți permisiuni de scriere pentru fișier. Dacă fișierul nu există, acesta va fi creat. Dacă fișierul există, atunci tot conținutul său este de obicei distrus fără niciun avertisment. n>> redirecționează de asemenea ieșirea din descriptorul fișierului n la dosar. De asemenea, trebuie să aveți permisiuni de scriere pentru fișier. Dacă fișierul nu există, acesta va fi creat. Dacă fișierul există, rezultatul este atașat la conținutul său.

Simbol nîn operatorii n> sau n>> este descriptor de fișier. Dacă nu este specificat, se presupune că este utilizat dispozitivul de ieșire standard. Lista 3 demonstrează operația de redirecționare pentru a separa rezultatul standard și eroarea standard a comenzii ls, folosind fișiere care au fost create mai devreme în directorul lpi103-4. Adăugarea ieșirii comenzii la fișierele existente este, de asemenea, demonstrată.

Lista 3. Redirecționarea ieșirii
$ ls x* z* ls: nu se poate accesa z*: Nu există un astfel de fișier sau director xaa xab $ ls x* z* >stdout.txt 2>stderr.txt $ ls w* y* ls: nu poate accesa w*: Nu așa fișier sau director yaa yab $ ls w* y* >>stdout.txt 2>>stderr.txt $ cat stdout.txt xaa xab yaa yab $ cat stderr.txt ls: nu se poate accesa z*: Nu există un astfel de fișier sau director ls: nu pot accesa w*: Nu există un astfel de fișier sau director

Am spus deja că redirecționarea ieșirii folosind operatorul n> de obicei duce la suprascriere fișierele existente. Puteți controla această proprietate folosind opțiunea noclobber a comenzii încorporate set. Dacă această opțiune este definită, o puteți suprascrie folosind operatorul n>|, așa cum se arată în Lista 4.

Lista 4. Redirecționarea ieșirii utilizând opțiunea noclobber
$ set -o noclobber $ ls x* z* >stdout.txt 2>stderr.txt -bash: stdout.txt: nu se poate suprascrie fișierul existent $ ls x* z* >|stdout.txt 2>|stderr.txt $ cat stdout.txt xaa xab $ cat stderr.txt ls: nu se poate accesa z*: Nu există un astfel de fișier sau director $ set +o noclobber #restore original noclobber setting

Uneori poate doriți să redirecționați atât ieșirea standard, cât și eroarea standard către un fișier. Acesta este adesea folosit în procesele automate sau locuri de muncă de fundal astfel încât să puteți vedea mai târziu rezultatele muncii dvs. Pentru a redirecționa ieșirea standard și eroarea standard către aceeași locație, utilizați operatorul &> sau &>>. Opțiune alternativă– descriptor de fișier de redirecționare nși apoi descriptorul fișierului mîn același loc folosind construcția m>&n sau m>>&n. În acest caz, ordinea în care firele sunt redirecționate este importantă. De exemplu, comanda
comanda 2>&1>output.txt
nu este același lucru cu o comandă
comanda >output.txt 2>&1
În primul caz, fluxul de erori stderr este redirecționat către locația curentă a fluxului stdout, iar apoi fluxul stdout este redirecționat către fișierul output.txt; cu toate acestea, a doua redirecționare afectează doar stdout și nu stderr. În al doilea caz, fluxul stderr este redirecționat către locația curentă a fluxului stdout, adică către fișierul output.txt. Aceste redirecționări sunt ilustrate în Lista 5. Observați în ultima comandă că ieșirea standard a fost redirecționată după fluxul de erori standard și, ca rezultat, fluxul de erori continuă să fie scos în fereastra terminalului.

Lista 5. Redirecționarea a două fluxuri către un fișier
$ ls x* z* &>output.txt $ cat output.txt ls: nu se poate accesa z*: Nu există un astfel de fișier sau director xaa xab $ ls x* z* >output.txt 2>&1 $ cat output.txt ls: nu se poate accesa z*: Nu există un astfel de fișier sau director xaa xab $ ls x* z* 2>&1 >output.txt # stderr nu merge la output.txt ls: nu poate accesa z*: Nu există un astfel de fișier sau director $ cat output. txt xaa xab

În alte situații, este posibil să doriți să ignorați în totalitate rezultatul standard sau eroarea standard. Pentru a face acest lucru, redirecționați firul corespunzător către dosar gol/dev/null. Lista 6 arată cum să ignorați fluxul de erori de comandă ls și cum să îl utilizați comenzi pisici asigurați-vă că fișierul /dev/null este de fapt gol.

Lista 6. Ignorarea erorii standard prin utilizarea /dev/null
$ ls x* z* 2>/dev/null xaa xab $ cat /dev/null

Redirecționare de intrare

La fel cum putem redirecționa stdout și stderr, putem redirecționa stdin dintr-un fișier folosind operatorul<. Если вы прочли руководство " ", то должны помнить, что в разделе была использована команда tr для замены пробелов в файле text1 на символы табуляции. В том примере мы использовали вывод команды cat чтобы создать стандартный поток ввода для команды tr . Теперь для преобразования пробелов в символы табуляции вместо бесполезного вызова команды cat мы можем использовать перенаправление ввода, как показано в листинге 7.

Lista 7. Redirecționare de intrare
$ tr " " "\t"

Interpreții de comandă, inclusiv bash, implementează conceptul aici-document, care este una dintre modalitățile de a redirecționa intrarea. Folosește designul<< и какое-либо слово, например END, являющееся маркером, или сигнальной меткой, означающей конец ввода. Эта концепция продемонстрирована в листинге 8.

Lista 8. Redirecționarea intrării utilizând conceptul aici-document
$sort -k2<1 măr > 2 pere > 3 banane > Sfârșit 1 măr 3 banane 2 pere

Dar de ce nu poți să tastați comanda sort -k2, să introduceți datele și să apăsați combinația Ctrl-d, indicând sfârşitul intrării? Desigur, puteți rula această comandă, dar atunci nu ați ști despre conceptul de document aici, care este foarte comun în scripturile shell (unde nu există altă modalitate de a specifica ce linii ar trebui acceptate ca intrare). Deoarece filele sunt utilizate pe scară largă în scripturi pentru a alinia textul și a le face mai ușor de citit, există o altă modalitate de a folosi conceptul de document aici. La folosirea operatorului<<- вместо оператора << начальные символы табуляции удаляются.

În Lista 9, am folosit înlocuirea comenzilor pentru a crea un caracter tabulator și apoi am creat un mic script shell care conține două comenzi cat, fiecare dintre ele citește date din blocul de document aici. Observați că am folosit cuvântul END pentru a semnala blocul de document aici pe care îl citim de la terminal. Dacă ar fi să folosim același cuvânt în scriptul nostru, intrarea noastră s-ar termina prematur. Prin urmare, în locul cuvântului END, folosim cuvântul EOF în script. Odată ce scriptul nostru este creat, folosim comanda. (punct) pentru a-l rula în contextul shell-ului curent.

Lista 9. Redirecționarea intrării utilizând conceptul aici-document
$ ht=$(echo -en "\t") $ cat<ex-aici.sh > cat<<-EOF >Apple > EOF > $(ht)cat<<-EOF >$(ht)pară > $(ht)EOF > Sfârșit $ pisică ex-aici.sh pisică<<-EOF apple EOF cat <<-EOF pear EOF $ . ex-here.sh apple pear

În articolele viitoare din această serie, veți afla mai multe despre înlocuirea comenzilor și scripting. Link-uri către toate articolele din această serie pot fi găsite în.

Crearea conductelor

Folosind comanda xargs

Comanda xargs citește datele de la dispozitivul de intrare standard și apoi construiește și execută comenzi care iau intrarea primită ca parametri. Dacă nu este specificată nicio comandă, este utilizată comanda echo. Lista 12 arată un exemplu simplu de utilizare a fișierului nostru text1, care conține trei rânduri a câte două cuvinte fiecare.

Lista 12. Utilizare comenzile xargs
$ cat text1 1 mar 2 pere 3 banane $ xargs

De ce atunci ieșirea xargs conține o singură linie? În mod implicit, xargs împarte intrarea dacă întâlnește caractere delimitare și fiecare fragment rezultat devine un parametru separat. Cu toate acestea, atunci când xargs construiește o comandă, aceasta este transmisă cât mai mulți parametri odată. Acest comportament poate fi modificat folosind opțiunea –n sau --max-args. Lista 13 prezintă un exemplu al ambelor opțiuni; un apel explicit la comanda echo a fost făcut și pentru utilizare cu xargs.

Lista 13. Utilizarea comenzilor xargs și echo
$xargs " args > 1 mar 2 pere 3 banane $ xargs --max-args 3 " args > 1 mere 2 args > pere 3 banane $ xargs -n 1 " args > 1 args > apple args > 2 args > pear args > 3 args > banane

În cazul în care datele de intrare conțin spații, dar sunt închise într-un singur sau ghilimele duble(sau spațiile sunt reprezentate ca secvențe de evacuare folosind bare oblice inverse), atunci xarg-urile nu le vor împărți în părți separate. Acest lucru este arătat în Lista 14.

Lista 14. Folosind comanda xargs și ghilimele
$ echo ""4 prune"" | text cat1 - 1 mar 2 pere 3 banane "4 prune" $ echo ""4 prune"" | text pisica1 - | xargs -n 1 1 mar 2 pere 3 banane 4 prune

Până acum, toate argumentele au fost adăugate la sfârșitul comenzii. Dacă aveți nevoie de alte argumente opționale care să fie adăugate după ele, utilizați opțiunea -I pentru a specifica un șir de înlocuire. În punctul din comanda numită prin xargs în care este folosit șirul de înlocuire, un argument va fi înlocuit. Cu această abordare, un singur argument este transmis fiecărei comenzi. Cu toate acestea, argumentul va fi creat din întregul șir de intrare, mai degrabă decât dintr-un fragment separat al acestuia. De asemenea, puteți utiliza opțiunea -L a comenzii xargs, care va face ca întregul șir să fie folosit ca argument, mai degrabă decât bucăți individuale separate prin spații. Utilizarea opțiunii -I determină implicit utilizarea opțiunii -L 1. Lista 15 prezintă exemple de utilizare a opțiunilor -I și –L.

Lista 15. Utilizarea comenzii xargs și a liniilor de intrare
$ xargs -I XYZ echo "START XYZ REPEAT XYZ END" " <9 plum> <3 banana><3 banana> <10 apple><10 apple>$ cat text1 text2 | xargs -L2 1 mar 2 pere 3 banane 9 prune 3 banane 10 mere

Deși exemplele noastre folosesc fișiere text simple, nu veți folosi adesea comanda xargs pentru astfel de cazuri. De obicei, veți avea de-a face cu o listă mare de fișiere rezultate din comenzi precum ls , find sau grep . Lista 16 arată o modalitate de a transmite xargs o listă a conținutului unui director unei comenzi precum grep.

Listarea 16. Utilizarea comenzii xargs și a listei de fișiere
$ ls |xargs grep "1" text1:1 apple text2:10 apple xaa:1 apple yaa:1

În ultimul exemplu, ce se întâmplă dacă unul sau mai multe nume de fișiere conține spații? Dacă încercați să utilizați comanda ca în Lista 16, veți primi o eroare. Într-o situație reală, lista de fișiere poate să nu fie obținută din comanda ls, ci, de exemplu, ca urmare a executării unui script de utilizator sau a unei comenzi; sau poate doriți să-l procesați în alte etape ale procesului de filtrare suplimentară. Deci nu ținem cont de faptul că ați putea folosi pur și simplu grep „1” * în loc de structura logică existentă.

În cazul comenzii ls, puteți folosi opțiunea --quoting-style pentru a forța ca numele fișierelor care conțin spații să fie incluse în paranteze (sau evadate). O soluție mai bună (când este posibil) este să folosiți opțiunea -0 a comenzii xargs, care face ca caracterele goale (\0) să fie folosite pentru a separa argumentele de intrare. Deși comanda ls nu are opțiunea de a utiliza nume de fișiere terminate cu nul ca rezultat, multe comenzi pot face acest lucru.

În Lista 17, vom copia mai întâi fișierul text1 în „text 1” și apoi vom oferi câteva exemple de utilizare a unei liste de nume de fișiere care conțin spații cu comanda xargs. Aceste exemple vă ajută să înțelegeți ideea, deoarece poate să nu fie atât de ușor să stăpâniți pe deplin lucrul cu xargs. În special, ultimul exemplu de conversie a liniilor noi în caractere goale nu ar funcționa dacă unele nume de fișiere ar conține deja linii noi. În următoarea secțiune a acestui articol, vom analiza o soluție mai robustă, folosind comanda find pentru a genera o ieșire adecvată care utilizează caractere nule ca delimitatori.

Lista 17. Utilizarea comenzii xargs și a fișierelor care conțin spații în numele lor
$ cp text1 "text 1" $ ls *1 |xargs grep "1" # text text1:1 apple grep: text: Nu există un astfel de fișier sau director grep: 1: Nu există un astfel de fișier sau director $ ls --quoting-style escape * 1 text1 text\ 1 $ ls --script shell-stil citate *1 text1 "text 1" $ ls --script shell-stil citate *1 |xargs grep "1" text1:1 apple text 1:1 apple $ # Ilustrați -0 opțiunea de xargs $ ls *1 | tr "\n" "\0" |xargs -0 grep "1" text1:1 apple text 1:1 apple

Comanda xargs nu poate construi comenzi arbitrar lungi. Astfel, în Linux, până la versiunea de kernel 2.26.3, lungimea maximă a comenzii a fost limitată. Dacă încercați să rulați o comandă precum rm somepath/* și directorul conține multe fișiere cu nume lungi, poate eșua cu o eroare care să afirme că lista de argumente este prea lungă. Dacă rulați versiuni mai vechi de Linux sau UNIX care pot avea aceste limitări, ar putea fi util să știți cum puteți utiliza xargs într-un mod care să le ocolească.

Puteți utiliza opțiunea --show-limits pentru a vedea limitele implicite pentru comanda xargs și opțiunea -s pentru a seta lungimea maximă a comenzilor afișate. Puteți afla despre alte opțiuni din paginile de manual.

Folosind comanda find cu opțiunea -exec sau împreună cu comanda xargs

În tutorialul „ ”, ați învățat cum să utilizați comanda find pentru a găsi fișiere pe baza numelor, timpilor de modificare, dimensiunilor și altor caracteristici. De obicei, anumite acțiuni trebuie efectuate asupra fișierelor găsite - ștergeți, copiați, redenumiți-le și așa mai departe. Ne vom uita acum la opțiunea -exec a comenzii find, care funcționează similar cu comanda find și apoi transmitem rezultatul comenzii xargs.

Lista 18. Folosind opțiunea find cu -exec
$ find text -exec cat text3()\; Aceasta este o propoziție. Aceasta este o propoziție. Aceasta este o propoziție. 1 măr 2 pere 3 banane Aceasta este o propoziție. Aceasta este o propoziție. Aceasta este o propoziție. 9 prune 3 banane 10 mere

Comparând rezultatele Listing 18 cu ceea ce știți deja despre xargs, veți observa câteva diferențe.

  1. Tu trebuie sa utilizați simbolurile () în comandă pentru a indica locația de înlocuire în care va fi înlocuit numele fișierului. Aceste caractere nu sunt adăugate automat la sfârșitul comenzii.
  2. Trebuie să terminați comanda cu un punct și virgulă, care trebuie să fie escape (\;, ";" sau ";").
  3. Comanda este executată o dată pentru fiecare fișier de intrare.

Încercați să rulați dvs. find text |xargs cat text3 pentru a vedea diferențele.

Acum să revenim la cazul în care numele fișierului conține spații. În Lista 19, am încercat să folosim comanda find cu opțiunea -exec în loc de comenzile ls și xargs.

Lista 19. Utilizarea comenzii find cu opțiunea -exec și fișiere care conțin spații în numele lor
$găsește. -nume „*1” -exec grep „1” () \; 1 mar 1 mar

Până acum, bine. Totuși, nu crezi că lipsește ceva aici? Ce fișiere conțineau liniile găsite de grep? Ceea ce lipsește aici sunt numele fișierelor, deoarece find apelează grep o dată pentru fiecare fișier, iar grep, fiind o comandă inteligentă, știe că, dacă i s-a dat doar numele unui fișier, nu trebuie să vă spună ce a fost.

În această situație, am putea folosi comanda xargs, dar știm deja despre problema cu fișierele ale căror nume conțin spații. Am menționat și faptul că comanda find poate genera o listă de nume delimitată de valori nule datorită opțiunii -print0. Versiunile moderne ale comenzii find pot fi separate nu printr-un punct și virgulă, ci printr-un semn +, astfel încât numărul maxim posibil de nume să poată fi transmis într-un singur apel la comanda find, la fel ca atunci când utilizați xargs . Inutil să spunem că în acest caz puteți utiliza construcția () o singură dată și că trebuie să fie ultimul parametru al comenzii. Lista 20 demonstrează ambele metode.

Lista 20. Utilizarea find , xargs și fișiere care conțin spații în numele lor
$găsește. -name "*1" -print0 |xargs -0 grep "1" ./text 1:1 apple ./text1:1 apple $ find . -name „*1” -exec grep „1” () + ./text 1:1 apple ./text1:1 apple

Ambele metode funcționează, iar alegerea uneia dintre ele este adesea determinată doar de preferințele personale ale utilizatorului. Fiți conștienți de faptul că puteți întâmpina probleme atunci când introduceți obiecte cu delimitatori bruti și spații albe; deci, dacă treceți ieșirea către xargs , utilizați opțiunea -print0 a find , precum și opțiunea -0 a xargs , care vă spune să utilizați delimitatori nuli în intrare. Alte comenzi, inclusiv tar , acceptă, de asemenea, opțiunea -0 și lucrează cu intrare delimitată de valori nule, așa că ar trebui să utilizați întotdeauna această opțiune pentru comenzile care o acceptă, cu excepția cazului în care sunteți 100% sigur că lista de intrări nu vă va produce probleme.

Ultimul nostru comentariu se referă la lucrul cu o listă de fișiere. Este o idee bună să vă verificați întotdeauna lista și comenzile cu atenție înainte de a efectua operațiuni în lot (cum ar fi ștergerea sau redenumirea mai multor fișiere). A avea o copie de rezervă actualizată atunci când este necesar poate fi, de asemenea, de neprețuit.

Divizarea ieșirii

Pentru a încheia acest articol, vom arunca o privire rapidă la încă o comandă. Uneori poate fi necesar să vizualizați rezultatul pe ecran și să îl salvați într-un fișier în același timp. Pentru asta tu am putea redirecționează ieșirea unei comenzi către un fișier dintr-o fereastră și apoi folosește tail -fn1 pentru a urmări rezultatul într-o altă fereastră, dar cel mai simplu mod este să folosești comanda tee.

Comanda tee este utilizată într-o conductă, iar argumentul său este numele fișierului (sau numele mai multor fișiere) către care va fi transmisă ieșirea standard. Opțiunea -a vă permite să nu înlocuiți conținutul vechi al fișierului cu conținut nou, ci să adăugați datele la sfârșitul fișierului. După cum sa discutat când am discutat despre pipelining, dacă doriți să stocați atât ieșirea standard, cât și fluxul de erori, trebuie să redirecționați stderr la stdout înainte de a transmite date ca intrare la comanda tee. Lista 21 prezintă un exemplu de utilizare a comenzii tee pentru a salva rezultatul în două fișiere, f1 și f2.

Lista 21. Împărțirea stdout folosind comanda tee
$ ls text|tee f1 f2 text1 text2 text3 $ cat f1 text1 text2 text3 $ cat f2 text1 text2 text3