Laten we eens een simpel probleem aanpakken: een lijst verkrijgen van de directory /usr/bin. Als we slechts ls /usr/bin opgeven, dan zullen een aantal bestanden bovenaan niet meer te zien zijn omdat deze van het scherm zijn verdwenen om de laatste bestanden te kunnen tonen. Hoe kunnen we alle bestanden te zien krijgen?
Het besturingssysteem Unix maakt het programma's erg makkelijk gebruik te maken van de terminal. Wanneer een programma iets naar je scherm schrijft, gebruikt het iets dat de standaarduitvoer wordt genoemd. Standaarduitvoer, afgekort tot stdout, is hoe het programma iets wegschrijft naar een gebruiker. Wat je aan een programma opgeeft, heet standaardinvoer (stdin). Een programma kan met de gebruiker communiceren zonder daarbij gebruik te maken van de standaardinvoer of -uitvoer, maar de meeste opdrachten die ik in dit boek behandel maken gebruik van stdin en stdout.
Met bijvoorbeeld de opdracht ls wordt de lijst met directory's naar standaarduitvoer weggeschreven, welke normaal gesproken is "verbonden" met je terminal. Een interactieve opdracht, zoals je shell bash, leest je opdrachten vanaf standaardinvoer.
Een programma kan ook naar standaardfout schrijven, aangezien het heel eenvoudig is het naast de standaarduitvoer naar je terminal te laten verwijzen. Standaardfout (stderr) is bijna altijd verbonden met een terminal zodat een echt mens de melding zal lezen.
In deze sectie gaan we drie manieren bestuderen om met de standaardinvoer en -uitvoer om te gaan: invoer- en uitvoeromleiding en pipes.
Een zeer belangrijke feature van Unix is de mogelijkheid om uitvoer om te leiden. Hiermee kun je het resultaat van een opdracht in een bestand opslaan of het direct naar een printer doorsturen in plaats dat je de resultaten van de opdracht op het scherm bekijkt. Om bijvoorbeeld de uitvoer van de opdracht ls /usr/bin om te leiden, plaatsen we een >-teken aan het einde van de regel, en geven we op in welk bestand we willen dat de uitvoer wordt opgeslagen:
/home/larry# ls /home/larry# ls -F /usr/bin > listing /home/larry# ls listing /home/larry# |
Zoals je kunt zien creëerde de opdracht een geheel nieuw bestand in je homedirectory in plaats dat het de namen van alle bestanden wegschreef. Laten we dit bestand eens proberen te bekijken met de opdracht cat. Terugkijkend zul je je herinneren dat cat een tamelijk onbruikbare opdracht was waarmee naar de terminal (de standaarduitvoer) werd gekopieerd wat je had ingetikt (de standaardinvoer). cat kan ook een bestand op standaarduitvoer afdrukken als je het bestand als parameter aan cat opgeeft:
/home/larry# cat listing ... /home/larry# |
De exacte uitvoer van de opdracht ls /usr/bin verscheen in de inhoud van listing. Alles goed en wel, het loste echter het oorspronkelijke probleem niet op.[1] Er valt echter meer te zeggen voordat we zover zijn.
De opdracht cat doet echter iets interessants wanneer de uitvoer ervan wordt omgeleid. Wat doet de opdracht cat listing > nieuwbestand? Normaal gesproken geeft de > nieuwbestand aan "neem alle uitvoer van de opdracht en plaats het in nieuwbestand." De uitvoer van de opdracht cat listing is het bestand listing. Dus we vonden een nieuwe (en niet zo efficiënte) methode om bestanden te kopiëren.
Hoe zit het met de opdracht cat > fox? cat op zichzelf leest elke regel in die in de terminal wordt getypt (standaardinvoer) en drukt het direct weer af (standaarduitvoer) totdat het een Ctrl-d tegenkomt. In dit geval werd de standaarduitvoer omgeleid naar het bestand fox. Nu dient cat als een rudimentaire editor:
/home/larry# cat > fox
The quick brown fox jumps over the lazy dog.
druk op Ctrl-d
|
We hebben nu het bestand fox aangemaakt met daarin de zin "The quick brown fox jumps over the lazy dog." Een laatste gebruik van de veelzijdige opdracht cat is om bestanden samen te voegen. cat zal elk bestand dat als parameter werd opgegeven, de een na de ander, afdrukken. Dus de opdracht cat listing fox zal de directorylisting van /usr/bin afdrukken en daarna zal het onze rare zin afdrukken. Dus met de opdracht cat listing fox > listandfox zal een nieuw bestand worden aangemaakt met de inhoud van zowel listing als fox.
Net als het omleiden van standaarduitvoer, is het ook mogelijk standaardinvoer om te leiden. In plaats dat een programma invoer vanaf je toetsenbord inleest, leest het dit uit een bestand. Aangezien invoeromleiding is gerelateerd aan uitvoeromleiding, lijkt het vanzelfsprekend het speciale teken voor invoeromleiding < te laten zijn. Ook dit wordt gebruikt na de opdracht die je wenst uit te voeren.
Gewoonlijk komt dit van pas als je een gegevensbestand hebt en een opdracht die invoer van standaardinvoer verwacht. De meeste opdrachten accepteren ook dat je een bestand opgeeft waarop het moet worden toegepast, dus < wordt in het dagelijks gebruik niet zoveel toegepast als andere technieken.
Veel Unix-opdrachten produceren een grote hoeveelheid informatie. Het is bijvoorbeeld bij een opdracht als ls /usr/bin niet ongewoon dat er meer uitvoer wordt geproduceerd dan je op je scherm kunt zien. Om alle informatie te kunnen zien die een opdracht als ls /usr/bin als uitvoer produceert, is een andere Unix opdracht nodig, genaamd more. [2] more pauzeert na elk scherm vol met informatie. Net als bij cat /etc/rc toont more < /etc/rc bijvoorbeeld het bestand /etc/rc, behalve dan dat more je de kans geeft het te lezen. more accepteert ook de opdracht /etc/rc, en dat is de normale wijze van aanroep.
Dat verhelpt echter nog niet het probleem dat ls /usr/bin meer informatie toont dan je kunt zien. more < ls /usr/bin werkt niet---invoeromleiding werkt alleen bij bestanden, niet bij opdrachten! Je zou dit kunnen doen:
/home/larry# ls /usr/bin > temp-ls /home/larry# more temp-ls ... /home/larry# rm temp-ls |
Unix voorziet echter in een veel zuivere manier om dat te doen. Je kunt gewoon de opdracht ls /usr/bin | more gebruiken. Het teken "|" duidt een pipe (pijp) aan. Net als een waterpijp, bestuurt een Unix-pijp de stroom. In plaats van water, besturen we de informatiestroom!
Een handige toepassing van pipes zijn programma's genaamd filters. Een filter is een programma dat de standaardinvoer leest, het op een of andere manier wijzigt, en op standaarduitvoer deze bewerking als uitvoer geeft. more is een filter; het leest de data in die het krijgt aangeleverd via de standaardinvoer en toont het per scherm op standaarduitvoer, je de mogelijkheid gevend het bestand te lezen. more is niet zo'n geweldig filter, omdat de uitvoer ervan niet geschikt is om naar een ander programma door te sturen.
Andere filters zijn de programma's cat, sort, head, en tail. Als je bijvoorbeeld alleen de eerste tien regels van de uitvoer van ls zou willen lezen, dan gebruik je de opdracht ls /usr/bin | head.
| [1] | Ongeduldige lezers kunnen de opdracht more uitproberen. |
| [2] | more wordt zo genoemd omdat dat de aanwijzing is die het van origine laat zien: --more--. In veel Linux-versies is de opdracht more identiek aan een geavanceerdere opdracht. Aangenomen dat computerprogrammeurs slechte blijspelspelers zijn, noemde ze dit nieuwe programma less (betekent: minder). |