[Linux scripting] Pipes

Een pipe (|) is een van de meest gebruikte tekens in Linux en UNIX shell scripts. Je kunt hiermee de standaard output (1) of standaard fout (2) van een script doorgeven als standaard input (0) van het volgende script.

Mochten de begrippen standaard input (0), standaard output (1) en standaard fout (2) een beetje zijn weggezakt, hier het schema:

IO Linux

Doe één ding, maar doe dat ene ding goed

De cultuur in Linux en UNIX is dat een commando of een script zich bezig houd met één enkel ding, en verder niets, maar dat ene ding dan ook zo goed mogelijk doet. Wil je een aantal (complexe) dingen doen is het een kwestie van de juiste scripts of commando's aan elkaar knopen.

Je kunt het vergelijken met een LEGO doos. Je krijgt een hele doos met steentjes en een handleiding waar je mee kunt bouwen wat je wilt. Je kunt de handleiding volgen en iets moois maken, maar je kunt ook je eigen creativiteit gebruiken om van die berg met steentjes zelf iets te bouwen. Zo ook in Linux. Om je een idee te geven hoeveel bouwsteentjes je hebt verwijs ik je door naar het Wikipedia lemma over GNU Coreutils.

Een praktisch voorbeeld

Stel je wilt de naam van je CPU weten, maar helaas is er nergens een sticker te bekennen op je computer en in de hardware eigenschappen kun je het ook niet vinden.

Dan kun je, in Linux, het bestand /proc/cpuinfo raadplegen. Hier staat zo'n beetje alle info over je CPU in die verzameld kan worden door je besturingssysteem. Hiervoor kun je $ cat gebruiken:

$ cat /proc/cpuinfo

Dan krijg je het volgende te zien (of iets wat er sterk op lijkt):

...
cpu cores         : 6
apicid            : 11
initial apicid    : 11
fpu                : yes
fpu_exception     : yes
cpuid level     : 20
wp                : yes
flags            : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts
bugs            :
bogomips        : 6801.19
clflush size    : 64
cache_alignment    : 64
address sizes    : 46 bits physical, 48 bits virtual
power management:

Dat is een aardige berg met info waar je doorheen moet gaan scrollen en lezen dan. Een beetje beheerder is lui, dus eens kijken of we met een pipe deze berg wat kunnen inkorten door te zoeken in de tekst. Zoeken in tekst kun je doen met $ grep

$ cat /proc/cpuinfo | grep 'model name'

Dan krijg je zoiets terug, wat al een stuk minder info is:

model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz
model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz

Je weet nu welke CPU je in je machine hebt zitten! In mijn geval weet je het 12 keer..

Je kunt hiermee door blijven gaan tot de output er precies zo uitziet als je wilt of nodig hebt. Om, bijvoorbeeld, het aantal items te reduceren tot één (of alle unieke, in speciale gevallen) kun je de vorige pipeline uitbreiden met $ uniq. Dit tooltje toont alleen unieke regels in tekst:

$ cat /proc/cpuinfo | grep 'model name' | uniq

Wat het volgende resultaat oplevert:

model name    : Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz

En stel dat je nu alles na de : wilt hebben, zonder rotzooi? Dan gebruik je $ cut en $ xargs:

$ cat /proc/cpuinfo | grep 'model name' | uniq | cut -d ':' -f2 | xargs

Wat het volgende resultaat geeft:

Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz

Bouwblokken

Zoals ook al hierboven gelinkt heb je in Linux een gigantisch aantal bouwblokken tot je beschikking om mee te spelen. In het volgende document heb ik mijn meestgebruikte kort beschreven met voorbeelden hoe ik ze gebruik.