Ik Van Linux

Doorverwijzen En Pijpen


Een rare titel misschien, maar deze is rechtstreeks vertaald uit het Engels Redirecting and Piping. Dit zijn twee trucjes die Bash heel krachtig maken.

Doorverwijzen

Normaal gesproken komt de input van een programma vanaf je toetsenbord (het stdin device 0). De output van een programma gaat naar het scherm (het stdout device 1), of het gaat naar het fout scherm (het stderr device 2).
Dat standaard gedrag kun je echter wijzigen. Het doorverwijzen van de output komt vaker voor dan het doorverwijzen van de input. Maar beide zijn mogelijk.

Doorverwijzen Van De Input

Het doorverwijzen van input doe je zo:

sort < /etc/mimi.types

Het vinden van een nuttig voorbeeld van input doorverwijzing voor beginners is een beetje lastig, maar ik hoop dat je snapt wat hier gebeurt. Het sort commando sorteert de input die je het geeft en stuurt het resultaat daarvan naar het scherm.
Dus je kunt het sort commando zonder parameters geven en dan gaat het programma staan wachten totdat je van alles intypt. Als je klaar bent met typen geef je dat met het End Of File teken Ctrl-D aan, waarna het programma de ingevoerde data gaat verwerken.
De output gaat dan naar je scherm, in gesorteerd vorm. Maar je kunt ook een bestand doorverwijzen naar het sort commando. Wat er dan eigenlijk gebeurt is dat de inhoud van dat bestand automatisch "getypt" wordt als input voor het programma wat op invoer aan het wachten is. Zodra het einde van het bestand wordt bereikt wordt automatisch het Ctrl-D teken toegevoegd, waarna het sort programma weer aan het werk gaat om alles gesorteerd af te drukken op het scherm.

Het doorverwijzen naar het sort programma is overigens een dom voorbeeld, want het programma kan namelijk naast hand getypte input ook meteen een of meer bestanden, die je als parameter meegeeft, sorteren. Dus bovenstaande commando had je ook zonder de doorverwijzing kunnen typen:

sort /etc/mimi.types

Maar zo zie je maar weer dat er vaak meerdere wegen naar Rome zijn.

Doorverwijzen Van De Output

Output doorverwijzing is veel gebruikelijker in Linux dan het doorverwijzen van de input. Ga maar eens in je home directory staan en type het volgende commando dan maar eens in:

ls -l /etc > lijst.txt

Je ziet niets gebeuren en krijgt meteen je Prompt weer terug. Maar ondertussen is er een bestand in je home directory geplaatst met de inhoud van de output van het ls -l /etc commando onder de naam lijst.txt . Bekijk die inhoud maar eens met het less lijst.txt commando. Dat is gemakkelijker te lezen dan wanneer je ls -l /etc gebruikt, want dat vliegt over het scherm en het meeste is al weer verdwenen voordat je met je ogen knippert.

Even wat technische achtergrond voordat we verder gaan, om beter te begrijpen wat er gebeurt. Alles in Linux zijn bestanden, dus ook devices. En daarom dus ook het stdout device, wat normaal de bestemming is van de tekst output van programma’s. Je kunt de bestemming van die output echter wijzigen naar een ander bestand. En dat doe je dus met het > teken, gevolgd door de bestandsnaam waar je de tekst naar toe wilt sturen.
En omdat devices ook bestanden zijn onder Linux mag je de output dus ook naar een ander device sturen. Een van de meest populaire andere devices is het /dev/null device. Het /dev/null device is de bodemloze put, waar je in kunt gooien wat je wil, je ziet het nooit meer terug. Dus ls -l /etc > /dev/null geeft helemaal geen output. Ik zeg dat fout, het geeft wel output, maar die wordt gestuurd naar /dev/null en die gooit alles gewoon meteen weg. Waarom dat handig kan zijn zien we zometeen.

Het > teken stuurt output van ons programma dus naar een bestand. Als dat bestand reeds bestaat wordt de inhoud daarvan overschreven door de output van ons programma.
Je kunt de output echter ook achter een bestaand bestand plakken door >> te gebruiken als doorverwijzer. Dus zo:

ls -l /etc/hostname >> lijst.txt

Ik heb boven al vernoemd dat er standaard twee output devices zijn. Een voor de normale output van ons programma (stdout), en een voor de foutmeldingen van ons programma (stderr). Je kunt de foutmeldingen van een programma dus apart van de normale output doorverwijzen. Zo doe je dat:

grep test /etc/* 2> /dev/null

Het grep commando wordt gebruikt om naar tekst te zoeken in een of meerdere bestanden. Het gebruik van dit programma zal ik een volgend hoofdstuk nog nader uitleggen. In ons voorbeeld zoeken we naar het woord test (hoofdlettergevoelig) in alle bestanden van de directory /etc . Maar door de 2> doorverwijzing worden de foutmeldingen echter naar /dev/null geschreven. En zoals we gezien hebben gooit /dev/null alles gewoon weg.
Op deze manier onderdrukken we de foutmeldingen die dit commando normaal gesproken zou hebben geproduceerd. Doe maar eens:

grep test /etc/*

En je zult zien dat er vele foutmeldingen zijn die zeggen dat sommige bestanden eigenlijk directories zijn en andere bestanden niet door een normale gebruiker gelezen mogen worden (permission denied). Door die vele foutmeldingen wordt de output van het programma wel erg onleesbaar.

Ben je alleen in de foutmeldingen geïnteresseerd, voor wat voor reden dan ook, dan doe je dit:

grep test /etc/* > /dev/null

Je had ook dit kunnen doen:

grep test /etc/* 1> /dev/null

Zoals je ziet is > gelijk aan 1> .

Tenslotte, voor de volledigheid, nog dit. Je kunt ook beide outputs, gescheiden, naar twee andere bestanden sturen.

grep test /etc/* > lijst.txt 2> /dev/null

Dit stuurt de normale output naar het bestand lijst.txt, terwijl de foutmeldingen naar /dev/null worden gestuurd.

En dan nog een toegift. Zowel stdout en stderr samen naar een andere bestemming sturen doe je zo:

grep test /etc/* > /dev/null 2>&1

Pijpen


Ik geef toe dat dit een beetje een ongelukkige vertaling van het Engelse werkwoord Piping is. Maar ja, jullie kozen er zelf voor om informatie over Linux in het Nederlands te willen lezen.

Met piping wordt bedoeld dat de output van een programma gebruikt wordt als input voor het volgende programma. Hiermee zijn zeer krachtige constructies te maken.
In Linux kiest men er vaak voor dat een bepaald programma zo min mogelijk kan, maar de dingen die het programma wel kan doet het programma ook goed. Daarom heb je soms meerdere programma’s nodig om wat ingewikkeldere taken uit te voeren.

Een voorbeeld moet dit wel weer verduidelijken:

ls /etc | wc
    179     179    1753

Het ls commando kennen we. Het | teken wordt het pipe teken genoemd. En het wc commando telt het aantal regels, woorden en letters dat je het als input aanbiedt. wc is de afkorting Word Count, maar telt dus meer dan alleen de woorden.
Mijn output wijkt waarschijnlijk af van die van jou, maar het eerste getal wat je ziet is het aantal regels, het tweede getal geeft het aantal woorden en het derde getal geeft het aantal letters van de output van het ls /etc commando. Hiermee kunnen we dus heel gemakkelijk zien dat er in totaal 179 bestanden en directories in de directory /etc staan.

Wat er dus eigenlijk gebeurt is dat de output van het ls /etc commando gestuurd wordt naar het wc commando. Merk op dat dit dus anders is dan bij doorverwijzingen. Bij doorverwijzingen wordt de output naar een bestand of device gestuurd. Bij piping wordt de output naar een ander commando gestuurd, die op zijn beurt die output als zijn input beschouwt.

Nog een klein grappig voorbeeldje:

cat /etc/hostname | rev
ipyrrebpsar

Zoals je ziet wordt de output van het cat /etc/hostname commando omgedraaid door het rev commando. Ik weet niet of dit nuttig te noemen valt, maar het is wel een grappige illustratie van wat je met piping voor elkaar kunt krijgen.

Nog Even Dit

In de voorbeelden hierboven gebruiken we de wc en rev commando's als proefkonijnen. Er zijn meerdere van dit soort programma's, die gewoon input op een bepaalde manier verwerken. Maar dat hoeft niet perse via piping te gebeuren. Zo kun je het wc programma ook gewoon handmatig gebruiken:

wc
Dit is een test om te testen of de test lukken wil.
En zoals je ziet kun je nu typen wat je wil.
Niets van wat je typt wordt als commando's beschouwd.
Maar zodra je op Ctrl-D drukt worden het aantal regels, woorden en letters geteld.
      4      46     234

Hier zie je dus dat je de input voor het wc commando ook gewoon zelf mag typen. Dat geldt natuurlijk ook voor het rev commando, en de vele andere commando's die we wellicht in de volgende hoofdstukken zullen tegenkomen:

rev
spiegelbeeld
dleeblegeips

Het rev commando wacht netjes op wat je daarna als input typt, en zodra je Enter drukt draait hij het die input om en wacht het op de volgen tekst die het om moet draaien. Je stopt het programma door Ctrl-D of Ctrl-C in te drukken.