Hva er stdin, stdout og stderr på Linux?

Terminalvindu på en Linux-datamaskin

Fatmawati Achmad Zaenuri/Shutterstock.com



|_+_|, |_+_| og |_+_| er tre datastrømmer som opprettes når du starter en Linux-kommando. Du kan bruke dem til å fortelle om skriptene dine sendes eller omdirigeres. Vi viser deg hvordan.

Strømmer slå sammen to punkter

Så snart du begynner å lære om Linux og Unix-lignende operativsystemer, vil du komme over begrepene |_+_|, |_+_| og |_+_|. Disse er tre standardstrømmer som opprettes når en Linux-kommando utføres. I databehandling er en strøm noe som kan overføre data. Når det gjelder disse strømmene, er disse dataene tekst.





Datastrømmer, som vannstrømmer, har to ender. De har en kilde og en utstrømning. Uansett hvilken Linux-kommando du bruker gir den ene enden av hver strøm. Den andre enden bestemmes av skallet som startet kommandoen. Den enden vil bli koblet til terminalvinduet, koblet til et rør eller omdirigert til en fil eller annen kommando, i henhold til kommandolinjen som startet kommandoen.

Linux Standard Streams

I Linux, |_+_| er standard inngangsstrøm. Dette godtar tekst som input. Tekstutdata fra kommandoen til skallet leveres via |_+_| (standard ut) stream. Feilmeldinger fra kommandoen sendes gjennom |_+_| (standard feil) strøm.



Så du kan se at det er to utdatastrømmer, |_+_| og |_+_|, og en inngangsstrøm, |_+_|. Fordi feilmeldinger og normal utgang hver har sin egen kanal for å føre dem til terminalvinduet, kan de håndteres uavhengig av hverandre.

Strømmer håndteres som filer

Strømmer i Linux – som nesten alt annet – behandles som om de var filer. Du kan lese tekst fra en fil, og du kan skrive tekst inn i en fil. Begge disse handlingene involverer en strøm av data. Så konseptet med å håndtere en strøm av data som en fil er ikke så mye strekk.

Annonse

Hver fil knyttet til en prosess er tildelt et unikt nummer for å identifisere den. Dette er kjent som filbeskrivelsen. Når det er nødvendig å utføre en handling på en fil, filbeskrivelsen brukes til å identifisere filen.



Disse verdiene brukes alltid for |_+_|, |_+_| og |_+_|:

  • 0 : stdin
  • en : stdout
  • to : stderr

Reagere på rør og omdirigeringer

For å lette noens introduksjon til et emne, er en vanlig teknikk å undervise i en forenklet versjon av emnet. For eksempel, med grammatikk, blir vi fortalt at regelen er I før E, bortsett fra etter C. Men faktisk der er flere unntak fra denne regelen enn det er tilfeller som adlyder det.

På samme måte, når man snakker om |_+_|, |_+_| og |_+_| det er praktisk å tro ut det aksepterte aksiomet at en prosess verken vet eller bryr seg om hvor de tre standardstrømmene avsluttes. Bør en prosess bry seg om utdataene går til terminalen eller omdirigeres til en fil? Kan den til og med fortelle om inndataene kommer fra tastaturet eller sendes inn i det fra en annen prosess?

Faktisk vet en prosess – eller i det minste kan den finne ut om den velger å sjekke – og den kan endre oppførselen tilsvarende hvis programvareforfatteren bestemte seg for å legge til denne funksjonaliteten.

Annonse

Vi kan se denne endringen i atferd veldig lett. Prøv disse to kommandoene:

stdin

stdout

Den |_+_| kommandoen oppfører seg annerledes hvis utgangen (|_+_|) blir overført til en annen kommando. Det er |_+_| som bytter til en enkelt kolonneutgang, er det ikke en konvertering utført av |_+_|. Og |_+_| gjør det samme hvis utgangen blir omdirigert:

stderr

stdin

Omdirigerer stdout og stderr

Det er en fordel å ha feilmeldinger levert av en dedikert strøm. Det betyr at vi kan omdirigere en kommandos utgang (|_+_|) til en fil og fortsatt se eventuelle feilmeldinger (|_+_|) i terminalvinduet. Du kan reagere på feilene hvis du trenger det, ettersom de oppstår. Det stopper også feilmeldingene fra å forurense filen som |_+_| har blitt omdirigert til.

Skriv inn følgende tekst i en editor og lagre den i en fil som heter error.sh.

stdout

Gjør skriptet kjørbart med denne kommandoen:

stederr

Den første linjen i skriptet ekko tekst til terminalvinduet, via |_+_| strøm. Den andre linjen prøver å få tilgang til en fil som ikke eksisterer. Dette vil generere en feilmelding som leveres via |_+_|.

Kjør skriptet med denne kommandoen:

stdin

Vi kan se at begge utdatastrømmene, |_+_| og |_+_|, har blitt vist i terminalvinduene.

La oss prøve å omdirigere utdataene til en fil:

stdout

Annonse

Feilmeldingen som leveres via |_+_| sendes fortsatt til terminalvinduet. Vi kan sjekke innholdet i filen for å se om |_+_| utdata gikk til filen.

stderr

Utgangen fra |_+_| ble omdirigert til filen som forventet.

Den |_+_| omdirigeringssymbol fungerer med |_+_| som standard. Du kan bruke en av de numeriske filbeskrivelsene for å indikere hvilken standard utdatastrøm du ønsker å omdirigere.

For å eksplisitt omdirigere |_+_|, bruk denne omdirigeringsinstruksjonen:

stdout

For å eksplisitt omdirigere |_+_|, bruk denne omdirigeringsinstruksjonen:

stderr

La oss prøve å prøve igjen, og denne gangen bruker vi |_+_|:

stdin

Feilmeldingen blir omdirigert og |_+_| |_+_| melding sendes til terminalvinduet:

La oss se hva som er i capture.txt-filen.

stdin

Den |_+_| meldingen er i capture.txt som forventet.

Omdirigerer Både stdout og stderr

Sikkert, hvis vi kan omdirigere enten |_+_| eller |_+_| til en fil uavhengig av hverandre, burde vi kunne omdirigere dem begge samtidig, til to forskjellige filer?

Annonse

Ja vi kan. Denne kommandoen vil lede |_+_| til en fil kalt capture.txt og |_+_| til en fil kalt error.txt.

stdout,

Fordi begge utdatastrømmene – standardutdata og standardfeil – blir omdirigert til filer, er det ingen synlig utdata i terminalvinduet. Vi blir returnert til ledeteksten som om ingenting har skjedd.

La oss sjekke innholdet i hver fil:

stderr stdin

Omdirigerer stdout og stderr til samme fil

Det er greit, vi har fått hver av standard utdatastrømmer til sin egen dedikerte fil. Den eneste andre kombinasjonen vi kan gjøre er å sende begge |_+_| og |_+_| til samme fil.

Vi kan oppnå dette med følgende kommando:

stdout

La oss bryte det ned.

  • ./error.sh : Starter skriptfilen error.sh.
  • > capture.txt : Omdirigerer |_+_| stream til capture.txt-filen. |_+_| er en forkortelse for |_+_|.
  • 2> & 1 : Dette bruker &> omdirigeringsinstruksjonen. Denne instruksjonen lar deg fortelle skallet å få en strøm til å komme til samme destinasjon som en annen strøm. I dette tilfellet sier vi omdiriger strøm 2, |_+_|, til samme destinasjon som strøm 1, |_+_|, blir omdirigert til.

Det er ingen synlig utgang. Det er oppmuntrende.

La oss sjekke capture.txt-filen og se hva som er i den.

stderr

Både |_+_| og |_+_| strømmer har blitt omdirigert til en enkelt destinasjonsfil.

For å få utdataene fra en strøm omdirigert og stille kastet bort, diriger utgangen til |_+_|.

Oppdager omdirigering i et skript

Vi diskuterte hvordan en kommando kan oppdage om noen av strømmene blir omdirigert, og kan velge å endre oppførselen deretter. Kan vi oppnå dette i våre egne manus? Ja vi kan. Og det er en veldig enkel teknikk å forstå og bruke.

Annonse

Skriv inn følgende tekst i en editor og lagre den som input.sh.

ls

Bruk følgende kommando for å gjøre den kjørbar:

stdout

Den smarte delen er test innenfor de firkantede parentesene . Den |_+_| (terminal) alternativet returnerer true (0) hvis filen assosiert med filbeskrivelsen avsluttes i terminalvinduet . Vi har brukt filbeskrivelsen 0 som argument for testen, som representerer |_+_|.

Hvis |_+_| er koblet til et terminalvindu, vil testen vise seg å være sann. Hvis |_+_| er koblet til en fil eller et rør, vil testen mislykkes.

Vi kan bruke hvilken som helst praktisk tekstfil for å generere input til skriptet. Her bruker vi en som heter dummy.txt.

ls

Utdataene viser at skriptet gjenkjenner at input ikke kommer fra et tastatur, det kommer fra en fil. Hvis du velger det, kan du variere skriptets oppførsel tilsvarende.

Annonse

Det var med en filomdirigering, la oss prøve det med en pipe.

cat

Skriptet gjenkjenner at inndata blir overført til det. Eller mer presist, den gjenkjenner igjen at |_+_| stream er ikke koblet til et terminalvindu.

La oss kjøre skriptet med verken pipes eller omdirigeringer.

ls

Den |_+_| stream er koblet til terminalvinduet, og skriptet rapporterer dette deretter.

For å sjekke det samme med utdatastrømmen, trenger vi et nytt skript. Skriv inn følgende i en editor og lagre den som output.sh.

stdout

Bruk følgende kommando for å gjøre den kjørbar:

stderr

Den eneste vesentlige endringen til dette skriptet er i testen i hakeparentesene. Vi bruker sifferet 1 for å representere filbeskrivelsen for |_+_|.

La oss prøve det. Vi sender utdataene gjennom |_+_|.

stdout

Annonse

Skriptet gjenkjenner at utdata ikke går direkte til et terminalvindu.

Vi kan også teste skriptet ved å omdirigere utdataene til en fil.

stdout

Det er ingen utgang til terminalvinduet, vi blir stille tilbake til ledeteksten. Som vi forventer.

Vi kan se inne i capture.txt-filen for å se hva som ble fanget. Bruk følgende kommando for å gjøre det.

stderr

Igjen, den enkle testen i skriptet vårt oppdager at |_+_| strømmen sendes ikke direkte til et terminalvindu.

Annonse

Hvis vi kjører skriptet uten pipes eller omdirigeringer, bør det oppdage at |_+_| blir levert direkte til terminalvinduet.

stdout

Og det er akkurat det vi ser.

Strømmer av bevissthet

Å vite hvordan du kan finne ut om skriptene dine er koblet til terminalvinduet, eller et rør, eller blir omdirigert, lar deg justere oppførselen deres deretter.

Logging og diagnostisk utdata kan være mer eller mindre detaljert, avhengig av om det går til skjermen eller til en fil. Feilmeldinger kan logges til en annen fil enn den vanlige programutgangen.

Som vanligvis er tilfellet, gir mer kunnskap flere alternativer.

Linux-kommandoer
Filer tjære · pv · katt · tac · chmod · grep · diff · sed · Med · Mann · pushd · popd · fsck · testdisk · seq · fd · pandoc · CD · $PATH · awk · bli med · jq · brette · unik · journalctl · hale · stat · ls · fstab · kastet ut · mindre · chgrp · chown · rev · se · strenger · type · endre navn · glidelås · pakke opp · montere · umount · installere · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · fra · ln · lapp · konvertere · rclone · makulere · SRM
Prosesser alias · skjerm · topp · hyggelig · renice · framgang · strace · system · tmux · chsh · historie · · parti · gratis · hvilken · dmesg · brukermod · ps · chroot · xargs · tty · rosa · lsof · vmstat · pause · vegg · ja · drepe · søvn · sudo · hans · tid · gruppeadd · brukermod · grupper · lshw · skru av · starte på nytt · Stoppe · strøm av · passwd · lscpu · crontab · Dato · bg · fg
Nettverk netstat · ping · traceroute · ip · ss · hvem er · fail2ban · bmon · du · finger · nmap · ftp · krølle · wget · hvem · hvem er jeg · I · iptables · ssh-keygen · ufw

I SLEKT: Beste Linux bærbare datamaskiner for utviklere og entusiaster

LES NESTE Profilbilde for Dave McKay Dave McKay
Dave McKay brukte først datamaskiner da stanset papirtape var på moten, og han har programmert siden. Etter over 30 år i IT-bransjen er han nå teknologijournalist på heltid. I løpet av sin karriere har han jobbet som frilansprogrammerer, leder for et internasjonalt programvareutviklingsteam, prosjektleder for IT-tjenester og sist som databeskyttelsesansvarlig. Hans forfatterskap har blitt publisert av howtogeek.com, cloudsavvyit.com, itenterpriser.com og opensource.com. Dave er en Linux-evangelist og forkjemper for åpen kildekode.
Les hele bio

Interessante Artikler