Pipeline (Unix) - Pipeline (Unix)
În Unix- ului de calculator sisteme de operare , o conductă este un mecanism de comunicare inter-proces utilizând un mesaj de trecere. O conductă este un set de procese înlănțuite între ele prin fluxurile lor standard , astfel încât textul de ieșire al fiecărui proces ( stdout ) este trecut direct ca intrare ( stdin ) la următorul. Al doilea proces este început, deoarece primul proces este încă în curs de executare și sunt executate simultan . Conceptul de conducte a fost susținut de Douglas McIlroy la casa ancestrală a Unix , Bell Labs, în timpul dezvoltării Unix, modelându-și filozofia cutiei de instrumente . Este numit prin analogie cu o conductă fizică . O caracteristică cheie a acestor conducte este „ascunderea internelor” (Ritchie și Thompson, 1974). La rândul său, aceasta permite mai multă claritate și simplitate în sistem.
Acest articol se referă la țevi anonime , unde datele scrise de un proces sunt tamponate de sistemul de operare până când sunt citite de următorul proces, iar acest canal unidirecțional dispare când procesele sunt finalizate. Aceasta diferă de țevile numite , unde mesajele sunt transmise către sau dintr-o țeavă numită făcându-l un fișier și rămâne după finalizarea proceselor. Sintaxa standard a shell-ului pentru țevile anonime este să listeze mai multe comenzi, separate prin bare verticale („țevi” în verbele comune Unix):
command1 | command2 | command3
De exemplu, pentru a lista fișierele din directorul curent ( ls ), păstrați doar liniile de ieșire ls care conțin șirul „cheie” ( grep ) și vizualizați rezultatul într-o pagină de derulare ( mai puțin ), un utilizator tastează următoarele în linia de comandă a unui terminal:
ls -l | grep key | less
Comanda ls -l
este executată ca un proces, a cărui ieșire (stdout) este conectată la intrarea (stdin) a procesului pentru grep key
; și la fel pentru procesul pentru less
. Fiecare proces preia intrări din procesul anterior și produce ieșiri pentru următorul proces prin fluxuri standard . Fiecare |
spune shell-ului să conecteze ieșirea standard a comenzii din stânga la intrarea standard a comenzii din dreapta printr-un mecanism de comunicare inter-proces numit o conductă (anonimă) , implementat în sistemul de operare. Țevile sunt unidirecționale; datele curg prin conductă de la stânga la dreapta.
Exemplu
Mai jos este un exemplu de conductă care implementează un fel de verificator ortografic pentru resursa web indicată de o adresă URL . Urmează o explicație a ceea ce face.
curl "https://en.wikipedia.org/wiki/Pipeline_(Unix)" |
sed 's/[^a-zA-Z ]/ /g' |
tr 'A-Z ' 'a-z\n' |
grep '[a-z]' |
sort -u |
comm -23 - <(sort /usr/share/dict/words) |
less
-
curl
obține conținutul HTML al unei pagini web (ar putea fi utilizatwget
pe unele sisteme). -
sed
înlocuiește toate caracterele (din conținutul paginii web) care nu sunt spații sau litere, cu spații. ( Newlines sunt păstrate.) -
tr
schimbă toate literele majuscule în minuscule și convertește spațiile din liniile de text în linii noi (fiecare „cuvânt” este acum pe o linie separată). -
grep
include numai linii care conțin cel puțin un caracter alfabetic minuscul (eliminarea oricăror linii goale). -
sort
sortează lista „cuvintelor” în ordine alfabetică, iar-u
comutatorul elimină duplicatele. -
comm
găsește linii în comun între două fișiere,-23
elimină liniile unice pentru al doilea fișier și cele comune pentru ambele, lăsând doar cele care se găsesc numai în primul fișier numit. În-
locul unui nume de fișier,comm
se folosește intrarea sa standard (de la conductă în acest caz).sort /usr/share/dict/words
sortează conținutulwords
fișierului în ordine alfabetică, așa cumcomm
se așteaptă, și<( ... )
scoate rezultatele într-un fișier temporar (prin substituirea procesului ), carecomm
citește. Rezultatul este o listă de cuvinte (linii) care nu se găsesc în / usr / share / dict / words. -
less
permite utilizatorului să parcurgă rezultatele.
Conducte în interfețele liniei de comandă
Toate shell-urile Unix utilizate pe scară largă au o construcție specială de sintaxă pentru crearea conductelor. In toate folosinta scrie comenzile în ordine, separate prin ASCII bara verticală caracter |
(care, din acest motiv, este adesea numit „caracter pipe“). Shell-ul pornește procesele și aranjează conexiunile necesare între fluxurile lor standard (inclusiv o cantitate de stocare tampon ).
Flux de erori
În mod implicit, fluxurile de erori standard („ stderr ”) ale proceselor dintr-o conductă nu sunt transmise prin conductă; în schimb, sunt îmbinate și direcționate către consolă . Cu toate acestea, multe shell-uri au o sintaxă suplimentară pentru schimbarea acestui comportament. În shell-ul csh , de exemplu, utilizarea |&
în loc de |
înseamnă că fluxul de erori standard ar trebui, de asemenea, să fie îmbinat cu ieșirea standard și să fie alimentat la următorul proces. Bourne Shell poate fuziona , de asemenea , eroare standard cu |&
deoarece bash 4.0 sau folosind 2>&1
, precum și redirecționeze către un alt fișier.
Pipemill
În cele mai frecvent utilizate conducte simple, shell-ul conectează o serie de subprocese prin conducte și execută comenzi externe în cadrul fiecărui subproces. Astfel, shell-ul în sine nu face nicio procesare directă a datelor care curg prin conductă.
Cu toate acestea, este posibil ca shell-ul să efectueze procesarea direct, utilizând așa-numita moară sau pipemill (deoarece o while
comandă este utilizată pentru a „mori” peste rezultatele din comanda inițială). Această construcție arată, în general, ca:
command | while read -r var1 var2 ...; do
# process each line, using variables as parsed into var1, var2, etc
# (note that this may be a subshell: var1, var2 etc will not be available
# after the while loop terminates; some shells, such as zsh and newer
# versions of Korn shell, process the commands to the left of the pipe
# operator in a subshell)
done
O astfel de pipemill nu poate funcționa așa cum s-a intenționat dacă corpul buclei include comenzi, cum ar fi cat
și ssh
, care se citesc din stdin
: pe prima iterație a buclei, un astfel de program (să-l numim drenaj ) va citi ieșirea rămasă din command
, și bucla se va termina apoi (cu rezultate în funcție de specificul scurgerii). Există câteva modalități posibile de a evita acest comportament. În primul rând, unele scurgeri acceptă o opțiune pentru a dezactiva citirea din stdin
(de exemplu ssh -n
). Alternativ, dacă canalul de scurgere nu are nevoie să citească nicio intrare stdin
pentru a face ceva util, poate fi dat < /dev/null
ca intrare.
Deoarece toate componentele unei țevi sunt rulate în paralel, un shell în mod obișnuit forchează un subproces (un subshell) pentru a gestiona conținutul acestuia, făcând imposibilă propagarea modificărilor variabile în mediul shell exterior. Pentru a remedia această problemă, "pipemill" poate fi în schimb alimentat dintr-un document de aici care conține o substituție de comandă , care așteaptă ca conducta să se finalizeze înainte de a freza conținutul. Alternativ, o țeavă numită sau o înlocuire de proces poate fi utilizată pentru execuția paralelă. GNU bash are, de asemenea, o lastpipe
opțiune pentru a dezactiva bifurcarea pentru ultima componentă a conductei.
Crearea conductelor programat
Conductele pot fi create sub controlul programului. pipe()
Apelul de sistem Unix solicită sistemului de operare să construiască un nou obiect anonim . Acest lucru are ca rezultat doi descriptori de fișiere noi, deschise în acest proces: capătul numai în citire al țevii și capătul numai în scriere. Capetele conductelor par a fi descriptori de fișiere anonimi normali , cu excepția faptului că nu au capacitatea de a căuta.
Pentru a evita blocajul și a exploata paralelismul, procesul Unix cu una sau mai multe conducte noi va apela, în general, fork()
pentru a crea noi procese. Fiecare proces va închide apoi capătul (conductele) conductei pe care nu le va folosi înainte de a produce sau consuma date. Alternativ, un proces poate crea fire noi și poate utiliza conducta pentru a comunica între ele.
Țevile denumite pot fi create de asemenea folosindmkfifo()
saumknod()
și apoi prezentate ca fișier de intrare sau de ieșire la programe pe măsură ce sunt invocate. Acestea permit crearea de țevi cu mai multe căi și sunt deosebit de eficiente atunci când sunt combinate cu redirecționarea erorilor standard sau cutee
.
Implementare
În majoritatea sistemelor de tip Unix, toate procesele unei conducte sunt pornite în același timp, cu fluxurile lor conectate corespunzător și gestionate de programator împreună cu toate celelalte procese care rulează pe mașină. Un aspect important al acestui fapt, diferențierea conductelor Unix de alte implementări de conducte, este conceptul de tamponare : de exemplu, un program de trimitere poate produce 5000 de octeți pe secundă , iar un program de recepție poate accepta doar 100 de octeți pe secundă, dar nu datele sunt pierdute. În schimb, ieșirea programului de trimitere este păstrată în buffer. Când programul de recepție este gata să citească date, atunci următorul program din conductă citește din buffer. În Linux, dimensiunea bufferului este de 65.536 octeți (64 KB). Un filtru open source terță parte numit bfr este disponibil pentru a oferi tampoane mai mari, dacă este necesar.
Conducte de rețea
Instrumente precum netcat și socat pot conecta conducte la prize TCP / IP .
Istorie
Conceptul de conducte a fost inventat de Douglas McIlroy și descris pentru prima dată în paginile manuale ale versiunii 3 Unix . McIlroy a observat că o mare parte din shell-urile de comandă au trecut fișierul de ieșire dintr-un program ca intrare în altul.
Ideile sale au fost puse în aplicare în 1973 când („într-o noapte febrilă”, a scris McIlroy) Ken Thompson a adăugat pipe()
apelul de sistem și conductele la shell și mai multe utilități în versiunea 3 Unix. „A doua zi”, a continuat McIlroy, „a văzut o orgie de neuitat a celor care se învârteau pe măsură ce toată lumea se alătura entuziasmului instalațiilor sanitare”. McIlroy îl recunoaște, de asemenea, pe Thompson cu |
notația, care a simplificat foarte mult descrierea sintaxei conductelor în versiunea 4 .
Deși dezvoltate independent, conductele Unix sunt legate de și au fost precedate de „fișierele de comunicare” dezvoltate de Ken Lochner în anii 1960 pentru Dartmouth Time Sharing System .
În procesele secvențiale de comunicare (CSP) ale lui Tony Hoare , conductele lui McIlroy sunt dezvoltate în continuare.
Robotul din pictograma pentru Apple 's Automator , care folosește, de asemenea, un concept de conductă pentru a înlănțui comenzi repetitive, ține o conductă în omagiu conceptului original Unix.
Alte sisteme de operare
Această caracteristică a Unix a fost împrumutată de alte sisteme de operare, cum ar fi MS-DOS și pachetul CMS Pipelines pe VM / CMS și MVS , și în cele din urmă a ajuns să fie desemnat modelul de proiectare a conductelor și filtrelor de inginerie software .
Vezi si
- Totul este un fișier - descrie una dintre caracteristicile definitorii ale Unix; conductele acționează asupra „fișierelor” în sensul Unix
- Conductă anonimă - o structură FIFO utilizată pentru comunicarea între procese
- GStreamer - un cadru multimedia bazat pe conducte
- Conducte CMS
- Iterat
- Țevi numite - țevi persistente utilizate pentru comunicații între procese
- Înlocuirea procesului - sintaxa shell pentru conectarea mai multor țevi la un proces
- Paralel GNU
- Pipeline (calcul) - alte conducte legate de computer
- Redirecționare (calcul)
- Tee (comandă) - o comandă generală pentru atingerea datelor dintr-o conductă
- Pipeline XML - pentru procesarea fișierelor XML
- xargs
Referințe
- Sal Soghoian pe MacBreak Episodul 3 "Enter the Automatrix"
linkuri externe
-
Istoricul notației Unix
- Memo-ul original al lui Doug McIlroy din 1964 , propunând pentru prima dată conceptul de țeavă
- Specificația unică UNIX , Ediția 7 din Grupul deschis : creați un canal interproces - Referința interfețelor de sistem,
- Pipes: o scurtă introducere de către Linux Information Project (LINFO)
- Unix Pipes - paradigmă de programare puternică și elegantă (Softpanorama)
- Analiza ad-hoc a datelor din linia de comandă Unix de la Wikibooks - Arată cum se utilizează conducte compuse din filtre simple pentru a face analize complexe de date.
- Utilizare și abuz de țevi cu date audio - Oferă o introducere în utilizarea și abuzul de țevi cu netcat, nettee și fifos pentru a reda audio într-o rețea.
- stackoverflow.com - Întrebări și răspunsuri despre manipularea conductelor bash.