Technisch is "/dev/null" een virtueel apparaat. Programma's benaderen dit als een echt bestand. Programma's kunnen uit virtuele apparaten gegevens ophalen (lezen). Maar deze gegevens worden niet van een schijf gelezen, maar door het besturingssysteem geleverd. Een ander voorbeeld is het bestand "/dev/zero".
In ons geval gaan we gegevens naar "/dev/null" sturen (schrijven). Maar alles wat naar "/dev/null" wordt geschreven, wordt genegeerd, vergeten, weggegooid. Om het nut daarvan te begrijpen, bekijken we eerst hoe standard output en standard error in Linux werken.
Een terminal opdracht kan twee soorten uitvoer produceren. Standaard uitvoer wordt naar stdout gestuurd en foutmeldingen naar stderr.
Standaard worden stdout en stderr geassocieerd met het terminal venster. Dit betekent dat alles wat naar stdout en stderr wordt gestuurd op het scherm wordt weergegeven. Met behulp van shell redirection kan je dit gedrag aanpassen. Zo kan je uitvoer in plaats van weer te geven, doorsturen (redirect) naar een bestand om het later te lezen of te analyseren. Of je kan de uitvoer sturen naar een fysiek apparaat zoals een LED of LCD scherm.
Stdout en stderr doorsturen via redirect:
2>
stuur je foutmeldingen (stderr) door. Een voorbeeld: 2>/dev/null
of 2>/home/gebruiker/error.log
.1>
stuur je standaard uitvoer (stdout) door.&>
stuur je zowel de foutmeldingen als de standaard uitvoer door.Daar er twee verschillende soorten uitvoer zijn, willen we één soort filteren. Een voorbeeld: we zoeken naar bestanden in de map /sys/ die iets te maken hebben met energie (power) instellingen.
dany@main:~> grep -r power /sys/
grep: /sys/kernel/slab/:d-0001024/remote_node_defrag_ratio: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/total_objects: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/alloc_calls: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/cpu_slabs: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/objects: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/objects_partial: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/cpu_partial: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/validate: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/free_calls: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/min_partial: Toegang geweigerd
...
grep: /sys/module/nvidia_modeset/sections/.note.gnu.build-id: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.text: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.data: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.altinstr_replacement: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.smp_locks: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/__bug_table: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.rodata.str1.1: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/__ksymtab_strings: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.altinstr_aux: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.rodata.str1.8: Toegang geweigerd
Door het enorme aantal bestanden die niet voor een gewone gebruiker toegankelijk zijn, krijg je massa's foutmeldingen.
Deze foutmeldingen zorgen ervoor dat het bijna onmogelijk is om de informatie die we willen zien, te vinden.
Daar "Toegang geweigerd" foutmeldingen via stderr worden weergegeven, kan je ze met de opdracht grep -r power /sys/ 2>/dev/null
naar "/dev/null" sturen.
Zoals je ziet, is dit veel leesbaarder.
In andere gevallen zijn enkel de foutmeldingen belangrijk. Een voorbeeld: om een netwerkverbinding te testen wordt dikwijls de ping opdracht gebruikt:
dany@main:~>ping google.com
PING google.com(par10s28-in-x0e.1e100.net (2a00:1450:4007:80a::200e)) 56 data bytes 64 bytes from par10s28-in-x0e.1e100.net (2a00:1450:4007:80a::200e): icmp_seq=1 ttl=118 time=18.0 ms 64 bytes from par10s28-in-x0e.1e100.net (2a00:1450:4007:80a::200e): icmp_seq=2 ttl=118 time=17.6 ms 64 bytes from par10s28-in-x0e.1e100.net (2a00:1450:4007:80a::200e): icmp_seq=3 ttl=118 time=17.6 ms 64 bytes from par10s28-in-x0e.1e100.net (2a00:1450:4007:80a::200e): icmp_seq=4 ttl=118 time=17.8 ms^C
--- google.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 17.640/17.809/18.032/0.227 ms
Deze opdracht blijft doorlopen tot je ze afsluit met de sneltoets Ctrl+c. De ping opdracht toont informatie over elke verbindingspoging, maar soms is het handiger om enkel de foutmeldingen weer te geven. We verwijderen de standaard uitvoer door deze naar het "/dev/null" apparaat te sturen:
dany@main:~> ping google.com 1>/dev/null
ping: sendmsg: Netwerk is onbereikbaar
ping: sendmsg: Netwerk is onbereikbaar
ping: sendmsg: Netwerk is onbereikbaar
ping: sendmsg: Netwerk is onbereikbaar
ping: sendmsg: Netwerk is onbereikbaar
Je krijgt nu enkel nog de foutmeldingen, namelijk bij netwerkonderbrekingen en dergelijke. De geslaagde verbindingen zien we niet langer, waardoor de focus op het opsporen van netwerkproblemen ligt.
Je kunt de standaard uitvoer en foutmeldingen ook naar verschillende locaties sturen. In het volgende voorbeeld zien we niets op het scherm, de standaarduitvoer wordt namelijk verwijdert en de foutmeldingen opgeslagen in het bestand error.log:
dany@main:~>ping google.com 1>/dev/null 2>error.log
^C
dany@main:~>cat error.log
ping: sendmsg: Netwerk is onbereikbaar ping: sendmsg: Netwerk is onbereikbaar ping: sendmsg: Netwerk is onbereikbaar ping: sendmsg: Netwerk is onbereikbaar ping: sendmsg: Netwerk is onbereikbaar ping: sendmsg: Netwerk is onbereikbaar dany@main:~>rm error.log
Soms is het handig om alle uitvoer te verwijderen. Dit kan op twee manieren.
dany@main:~> grep -r power /sys/ >/dev/null 2>&1
Met >/dev/null
stuur je de standaard uitvoer naar "/dev/null" en 2>&1
stuurt de foutmeldingen (stderr) naar de standaard uitvoer (stdout).
Hier gebruiken we &1
in plaats van gewoon 1
, omdat je met 2>1
de standaard uitvoer naar het bestand met de naam "1" zou sturen.
Ook de volgorde is belangrijk, bij het omkeren van de redirect parameters, krijg je een heel ander resultaat.
dany@main:~> grep -r power /sys/ 2>&1 >/dev/null
grep: /sys/kernel/slab/:d-0001024/remote_node_defrag_ratio: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/total_objects: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/alloc_calls: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/cpu_slabs: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/objects: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/objects_partial: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/cpu_partial: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/validate: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/free_calls: Toegang geweigerd
grep: /sys/kernel/slab/:d-0001024/min_partial: Toegang geweigerd
...
grep: /sys/module/nvidia_modeset/sections/.note.gnu.build-id: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.text: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.data: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.altinstr_replacement: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.smp_locks: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/__bug_table: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.rodata.str1.1: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/__ksymtab_strings: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.altinstr_aux: Toegang geweigerd
grep: /sys/module/nvidia_modeset/sections/.rodata.str1.8: Toegang geweigerd
Bij het interpreteren van 2>&1
worden de foutmeldingen (stderr) naar de standaard uitvoer (stdout) gestuurd en op het scherm weergegeven.
Daarna wordt de standaard uitvoer (stdout) verwijderd door deze naar "/dev/null" te sturen.
Het resultaat is dat je de foutmeldingen op het scherm ziet verschijnen en niet alle uitvoer wordt onderdrukt.
Heb je moeite om de correcte volgorde te onthouden, gebruik dan de volgende alternatieve opdracht om alle uitvoer te onderdrukken:
dany@main:~> grep -r power /sys/ &>/dev/null
De parameter &>/dev/null
zorgt dat beide uitvoertypes naar het zwarte gat worden gestuurd.
Veronderstel dat je de sequentiële leessnelheid van een schijf wilt meten.
De test is niet zeer nauwkeurig, maar nauwkeurig genoeg.
We gebruiken de dd opdracht die de uitvoer zowel naar stdout als een bestand kan schrijven.
Je kunt dd dus ook naar het virtuele bestand "/dev/null" laten schrijven.
De dd parameter of=/dev/null
zorgt daarvoor.
Je hoeft dus niet eens van redirection gebruik te maken.
De if=
parameter bepaald welk bestand je wilt lezen, om het vervolgens naar het bestand vermeld bij of=
te schrijven.
dany@main:~> dd if=Downloads/systemrescue-7.01-amd64.iso of=/dev/null status=progress bs=1M iflag=direct
593494016 bytes (593 MB, 566 MiB) copied, 3 s, 197 MB/s
699+0 records gelezen
699+0 records geschreven
732954624 bytes (733 MB, 699 MiB) copied, 3,70987 s, 198 MB/s
Je kunt deze truc ook gebruiken om de downloadsnelheid van een server te bepalen, zonder iets naar een bestand te schrijven. Schrijf het gedownloade bestand gewoon naar "/dev/null".
dany@main:~> wget -O /dev/null https://osdn.net/projects/systemrescuecd/storage/releases/7.01/systemrescue-7.01-amd64.iso
--2020-12-27 15:05:54-- https://osdn.net/projects/systemrescuecd/storage/releases/7.01/systemrescue-7.01-amd64.iso
Herleiden van osdn.net (osdn.net)... 202.221.179.17
Verbinding maken met osdn.net (osdn.net)|202.221.179.17|:443... verbonden.
HTTP-verzoek is verzonden; wachten op antwoord... 302 Found
Locatie: https://osdn.net/frs/redir.php?m=dotsrc&f=%2Fstorage%2Fg%2Fs%2Fsy%2Fsystemrescuecd%2Freleases%2F7.01%2Fsystemrescue-7.01-amd64.iso [volgen...]
--2020-12-27 15:05:55-- https://osdn.net/frs/redir.php?m=dotsrc&f=%2Fstorage%2Fg%2Fs%2Fsy%2Fsystemrescuecd%2Freleases%2F7.01%2Fsystemrescue-7.01-amd64.iso
Verbinding met osdn.net:443 wordt hergebruikt.
HTTP-verzoek is verzonden; wachten op antwoord... 302 Found
Locatie: https://dotsrc.dl.osdn.net/osdn/storage/g/s/sy/systemrescuecd/releases/7.01/systemrescue-7.01-amd64.iso [volgen...]
--2020-12-27 15:05:55-- https://dotsrc.dl.osdn.net/osdn/storage/g/s/sy/systemrescuecd/releases/7.01/systemrescue-7.01-amd64.iso
Herleiden van dotsrc.dl.osdn.net (dotsrc.dl.osdn.net)... 2001:878:346::116, 130.225.254.116
Verbinding maken met dotsrc.dl.osdn.net (dotsrc.dl.osdn.net)|2001:878:346::116|:443... verbonden.
HTTP-verzoek is verzonden; wachten op antwoord... 200 OK
Lengte: 732954624 (699M) [application/octet-stream]
Wordt opgeslagen als: ‘/dev/null’
/dev/null 100%[==========================================================>] 699,00M 9,79MB/s in 67s
2020-12-27 15:07:03 (10,4 MB/s) - '‘/dev/null’' opgeslagen [732954624/732954624]