Master Linux-pipes: Øk effektiviteten din nå!

Bruk Linux-rør for å koordinere samspillet mellom kommandolinjeverktøy. Ved å kombinere en rekke uavhengige kommandoer til et effektivt team, kan du forenkle komplekse prosesser og øke produktiviteten. La oss se hvordan dette fungerer.

Rør er allestedsnærværende

Rør er en av de mest essensielle funksjonene i kommandolinjen for Linux og Unix-baserte systemer. De brukes på utallige måter. Uansett hvilken artikkel om Linux-kommandolinjen du leser, vil du nesten garantert se rør i bruk. Ved å se gjennom en rekke artikler om emnet har det blitt tydelig at rør er en grunnleggende del av Linux-kommandoer.

Med Linux-rør kan du utføre handlinger som ikke er direkte støttet av skallet. Linux sin filosofi handler om å ha mange små verktøy som er spesialiserte og gjør jobben sin godt. Dette prinsippet, ofte referert til som «gjør én ting og gjør det bra,» tillater deg å kombinere kommandoer via rør. Utdataene fra én kommando blir input for den neste. Hver kommando bidrar med sin unike egenskap til laget, og du kan sette sammen et kraftfullt team av verktøy.

Et grunnleggende eksempel

La oss anta at du har en mappe med mange forskjellige filtyper og du ønsker å finne ut hvor mange filer av en spesiell type som finnes i den mappen. Selv om det finnes alternative metoder for å gjøre dette, skal vi bruke rør i dette eksemplet for å illustrere konseptet.

Først kan vi bruke kommandoen `ls` for å få en oversikt over alle filene:

ls

For å isolere filtypen vi er interessert i, kan vi bruke kommandoen `grep`. Vi skal søke etter filer som har ordet «side» i navnet eller filendelsen.

Vi bruker spesialtegnet «|» fra skallet for å videresende utdata fra `ls` til `grep`:

ls | grep "page"

`grep` skriver ut linjer som matcher søkemønsteret. Dette gir oss en liste over kun «.page»-filer.

Selv dette enkle eksemplet viser hvordan rør fungerer. Utdataene fra `ls` blir ikke sendt direkte til terminalvinduet, men i stedet til `grep` som jobber med dataene. Utdataene vi ser kommer fra `grep`, som er den siste kommandoen i denne kjeden.

Utvider kommando-kjeden

La oss fortsette å utvide kommando-kjeden vår. For å telle antall .page-filer, kan vi legge til kommandoen `wc`. Vi skal bruke valget `-l` (linjetelling) sammen med `wc`. Legg merke til at vi også har lagt til `-l` (langt format) til `ls`. Dette vil vi bruke snart.

ls -l | grep "page" | wc -l

Siden `grep` ikke lenger er den siste kommandoen, ser vi ikke utdataene fra den. Utdataene fra `grep` sendes til `wc`. Utdataene vi ser i terminalen kommer nå fra `wc`. Den melder at det er 69 «.page»-filer i mappen.

La oss utvide dette igjen. Vi erstatter `wc` med kommandoen `awk`. Utdataene fra `ls -l` har ni kolonner. Vi kan bruke `awk` for å skrive ut kolonne fem, tre og ni. Disse kolonnene representerer størrelsen, eieren og navnet på filen.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}'

Dette gir oss en liste over de utvalgte kolonnene for hver av de samsvarende filene.

Vi sender nå utdataene gjennom kommandoen `sort`. Vi bruker valget `-n` (numerisk) slik at `sort` behandler den første kolonnen som tall.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n

Utdataene er nå sortert etter filstørrelse, med vårt tilpassede utvalg av tre kolonner.

Legge til enda en kommando

Til slutt legger vi til kommandoen `tail`. Vi skal bruke den til å vise de siste fem linjene av utdataene.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5

Denne kommandoen kan oversettes til «vis meg de fem største «.page»-filene i denne mappen, sortert etter størrelse». Det finnes ingen enkelt kommando for dette, men ved å bruke rør har vi skapt vår egen. Vi kan lagre denne eller andre lange kommandoer som et alias eller en skallfunksjon for å unngå å skrive den inn hver gang.

Her er utdataene:

Vi kan reversere sorteringsrekkefølgen ved å legge til valget `-r` (revers) til sorteringskommandoen og bruke `head` istedenfor `tail` for å vise de første linjene fra utdataene.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -nr | head -5

Denne gangen er de fem største «.page»-filene oppført fra størst til minst.

Noen nyere eksempler

Her er et par eksempler fra nylige artikler om dette temaet:

Noen kommandoer, som for eksempel `xargs`, er designet for å ta input fra rør. Her er en måte vi kan få `wc` til å telle ord, tegn og linjer i flere filer. Utdataene fra `ls` sendes til `xargs`, som sender listen over filnavn til `wc`, som om de var sendt til `wc` som kommandolinjeparametere.

ls *.page | xargs wc

Det totale antallet ord, tegn og linjer er oppført nederst i terminalvinduet.

Her er en måte å hente en sortert liste over unike filtyper i den nåværende mappen med en telling av hver type:

ls | rev | cut -d'.' -f1 | rev | sort | uniq -c

Det skjer mye her:

`ls`: Viser filene i mappen.
`rev`: Reverserer teksten i filnavnene.
`cut`: Kutter av strengen ved første forekomst av skilletegnet «.». Tekst etter dette forkastes.
`rev`: Reverserer den gjenværende teksten, som nå er filtypen.
`sort`: Sorterer listen alfabetisk.
`uniq`: Teller antall unike oppføringer i listen.

Utdataene viser listen over filendelser, sortert alfabetisk med en telling av hver unik type.

Navngitte rør

Det finnes en annen type rør, kjent som navngitte rør. Rørene vi har sett på til nå, opprettes dynamisk av skallet mens det behandler kommandolinjen. De opprettes, brukes og kastes deretter. De er midlertidige og etterlater ingen spor. De eksisterer bare mens kommandoen som bruker dem kjører.

Navngitte rør vises som permanente objekter i filsystemet, slik at du kan se dem ved å bruke `ls`. De er permanente siden de vil overleve en omstart av datamaskinen, men alle uleste data i dem vil slettes.

Navngitte rør ble en gang brukt til å la forskjellige prosesser sende og motta data, men dette er ikke like vanlig i dag. Det finnes nok fortsatt de som bruker dem, men de er ikke så utbredt. Men for fullstendighetens skyld skal vi vise hvordan du bruker dem.

Navngitte rør opprettes med kommandoen `mkfifo`. Denne kommandoen vil opprette et navngitt rør med navnet «geek-pipe» i den nåværende mappen.

mkfifo geek-pipe

Vi kan se detaljene til det navngitte røret ved hjelp av `ls` med valget `-l` (langt format):

ls -l geek-pipe

Det første tegnet i oppføringen er «p», som betyr at dette er et rør. Hvis det var en «d» ville det vært en mappe, og en bindestrek «-» ville betydd at det er en vanlig fil.

Bruke det navngitte røret

La oss nå bruke røret vårt. De anonyme rørene vi brukte tidligere, sendte dataene umiddelbart fra avsenderkommandoen til mottakerkommandoen. Data sendt gjennom et navngitt rør vil bli værende i røret til de leses. Dataene lagres i minnet, så størrelsen på det navngitte røret vil ikke endre seg i `ls`-oppføringene, uansett om det finnes data i det eller ikke.

Vi trenger to terminalvinduer for dette eksemplet. Vi merker dem slik:

# Terminal-1

i det ene terminalvinduet, og

# Terminal-2

i det andre, for å gjøre det enklere å skille dem. Hashtegnet «#» forteller skallet at dette er en kommentar som skal ignoreres.

La oss bruke hele det forrige eksemplet vårt og omdirigere det til det navngitte røret. Vi bruker både anonyme og navngitte rør i én kommando:

ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipe

Det ser ikke ut som om det skjer så mye. Du vil derimot legge merke til at du ikke får tilbake ledeteksten, så det er noe som foregår.

I det andre terminalvinduet, kjør følgende kommando:

cat < geek-pipe

Vi omdirigerer innholdet i det navngitte røret til `cat`, slik at `cat` viser innholdet i det andre terminalvinduet. Her er utdataene:

Og du vil se at du har fått tilbake ledeteksten i det første terminalvinduet.

Hva skjedde nå?

Vi omdirigerte noen utdata til det navngitte røret.
Det første terminalvinduet returnerte ikke til ledeteksten.
Dataene ble værende i røret til de ble lest fra røret i den andre terminalen.
Vi ble returnert til ledeteksten i det første terminalvinduet.

Du tenker kanskje at du kan kjøre kommandoen i det første terminalvinduet som en bakgrunnsoppgave ved å legge til et `&` på slutten av kommandoen. Og du har rett. I det tilfellet hadde vi fått tilbake ledeteksten umiddelbart.

Poenget med å ikke bruke bakgrunnsbehandling var å understreke at et navngitt rør er en blokkerende prosess. Å legge noe inn i et navngitt rør åpner bare den ene enden av røret. Den andre enden åpnes ikke før leseprogrammet trekker ut dataene. Kjernen setter prosessen i det første terminalvinduet i ventemodus til dataene leses fra den andre enden av røret.

Kraften i rør

Navngitte rør er litt av en kuriositet i dag.

De vanlige Linux-rørene, derimot, er et av de mest nyttige verktøyene du kan ha i verktøykassen i terminalvinduet. Du vil oppleve at Linux-kommandolinjen kommer til liv og gir deg en ny form for kraft, når du kan orkestrere en rekke kommandoer til å skape én sammenhengende utførelse.

Avsluttende tips: Det er best å skrive kommandoene ved å legge til en kommando om gangen, og sørge for at den delen fungerer, før du legger til den neste.