Hvad er stdin, stdout og stderr på Linux?

stdin,, stdoutog stderrer tre datastrømme oprettet, når du starter en Linux-kommando. Du kan bruge dem til at fortælle, om dine scripts bliver pipet eller omdirigeret. Vi viser dig hvordan.

Strømme deltager i to point

Så snart du begynder at lære om Linux og Unix-lignende operativsystemer, vil du komme på tværs af de vilkår stdin, stdoutog stederr. Dette er tre standardstrømme, der oprettes, når en Linux-kommando udføres. I computing er en stream noget, der kan overføre data. I tilfælde af disse streams er disse data tekst.

Datastrømme, som vandstrømme, har to ender. De har en kilde og en udstrømning. Uanset hvilken Linux-kommando du bruger, har den ene ende af hver stream. Den anden ende bestemmes af skallen, der startede kommandoen. Denne ende forbindes med terminalvinduet, forbindes til et rør eller omdirigeres til en fil eller anden kommando i henhold til kommandolinjen, der startede kommandoen.

Linux Standard Streams

I Linux  stdiner standardindgangsstrømmen. Dette accepterer tekst som input. Tekstoutput fra kommandoen til skallen leveres via stdoutstrømmen (standard ud). Fejlmeddelelser fra kommandoen sendes gennem stderrstrømmen (standardfejl).

Så du kan se, at der er to output streams, stdoutog stderr, og en input stream, stdin. Da fejlmeddelelser og normal output hver har deres egen kanal til at føre dem til terminalvinduet, kan de håndteres uafhængigt af hinanden.

Streams håndteres som filer

Streams i Linux - som næsten alt andet - behandles som om de var filer. Du kan læse tekst fra en fil, og du kan skrive tekst i en fil. Begge disse handlinger involverer en strøm af data. Så begrebet håndtering af en datastrøm som en fil er ikke så meget af en strækning.

Hver fil tilknyttet en proces tildeles et unikt nummer til at identificere den. Dette er kendt som filbeskrivelsen. Når der kræves en handling på en fil, bruges filbeskrivelsen til at identificere filen.

Disse værdier bruges altid til stdin, stdout,og stderr:

  • 0 : stdin
  • 1 : stdout
  • 2 : stderr

Reagerer på rør og omdirigeringer

For at lette en persons introduktion til et emne er en almindelig teknik at undervise i en forenklet version af emnet. For eksempel med grammatik får vi at vide, at reglen er "jeg før E undtagen efter C." Men faktisk er der flere undtagelser fra denne regel, end der er tilfælde, der adlyder den.

På samme måde, når vi taler om stdin, stdoutog stderr det er praktisk at trave det accepterede aksiom, at en proces hverken ved eller bryr sig om, hvor dens tre standardstrømme afsluttes. Skal en proces være ligeglad med, om dens output går til terminalen eller omdirigeres til en fil? Kan det overhovedet fortælle, om dets input kommer fra tastaturet eller bliver ledt til det fra en anden proces?

Faktisk ved en proces - eller i det mindste den kan finde ud af, hvis den vælger at kontrollere - og den kan ændre sin adfærd i overensstemmelse hermed, hvis softwareforfatteren besluttede at tilføje denne funktionalitet.

Vi kan se denne ændring i adfærd meget let. Prøv disse to kommandoer:

ls

ls | kat

De lskommando opfører sig anderledes, hvis dens output ( stdout) bliver pipes i en anden kommando. Det er,  lsder skifter til en enkelt kolonneoutput, det er ikke en konvertering udført af cat. Og lsgør det samme, hvis dets output omdirigeres:

ls> capture.txt

cat capture.txt

Omdirigering af stdout og stderr

Der er en fordel ved at have fejlmeddelelser leveret af en dedikeret stream. Det betyder, at vi kan omdirigere en kommandos output ( stdout) til en fil og stadig se eventuelle fejlmeddelelser ( stderr) i terminalvinduet. Du kan reagere på fejlene, hvis du har brug for det, da de opstår. Det stopper også fejlmeddelelserne i at forurene den fil, der stdouter omdirigeret til.

Skriv følgende tekst i en editor og gem den i en fil kaldet error.sh.

#! / bin / bash echo "Om at prøve at få adgang til en fil, der ikke findes" cat bad-filename.txt

Gør scriptet eksekverbart med denne kommando:

chmod + x-fejl. sh

Den første linje i scriptet ekko tekst til terminalvinduet via  stdoutstrømmen. Den anden linje forsøger at få adgang til en fil, der ikke findes. Dette genererer en fejlmeddelelse, der leveres via stderr.

Kør scriptet med denne kommando:

./fejl.sh

Vi kan se, at begge outputstrømme stdoutog stderrer blevet vist i terminalvinduerne.

Lad os prøve at omdirigere output til en fil:

./error.sh> capture.txt

Fejlmeddelelsen, der leveres via, stderrsendes stadig til terminalvinduet. Vi kan kontrollere indholdet af filen for at se, om stdout output gik til filen.

cat capture.txt

Outputtet fra stdinblev omdirigeret til filen som forventet.

Den >omdirigering symbol arbejder med stdoutsom standard. Du kan bruge en af ​​de numeriske filbeskrivelser til at angive, hvilken standardoutputstrøm du vil omdirigere.

For at eksplicit omdirigere  stdoutskal du bruge denne omdirigeringsinstruktion:

1>

For at eksplicit omdirigere  stderrskal du bruge denne omdirigeringsinstruktion:

2>

Lad os prøve vores test igen, og denne gang bruger vi 2>:

./error.sh 2> capture.txt

Fejlmeddelelsen omdirigeres, og stdoutechomeddelelsen sendes til terminalvinduet:

Lad os se, hvad der er i capture.txt-filen.

cat capture.txt

Det stderrbudskab er i capture.txt som forventet.

Omdirigering af både stdout og stderr

Hvis vi kan omdirigere en stdouteller stderren fil uafhængigt af hinanden, burde vi helt sikkert være i stand til at omdirigere dem begge på samme tid til to forskellige filer?

Ja vi kan. Denne kommando dirigerer stdouttil en fil kaldet capture.txt og stderrtil en fil kaldet error.txt.

./error.sh 1> capture.txt 2> error.txt

Da begge strømme af output - standardoutput og standardfejl - omdirigeres til filer, er der ingen synlig output i terminalvinduet. Vi returneres til kommandolinjeprompten, som om der ikke er sket noget.

Lad os kontrollere indholdet af hver fil:

cat capture.txt
cat error.txt

Omdirigering af stdout og stderr til samme fil

Det er pænt, vi har hver af de standardudgangsstrømme, der går til sin egen dedikerede fil. Den eneste anden kombination, vi kan gøre, er at sende begge stdoutog stderrtil den samme fil.

Vi kan opnå dette med følgende kommando:

./error.sh> capture.txt 2> & 1

Lad os nedbryde det.

  • ./error.sh : Starter scriptfilen error.sh.
  • > capture.txt : Omdirigerer stdoutstrømmen til capture.txt-filen. >er stenografi for 1>.
  • 2> & 1 : Dette bruger instruktionen &> omdirigering. Denne instruktion giver dig mulighed for at fortælle skallen at få en stream til den samme destination som en anden stream. I dette tilfælde siger vi "omdirigere strøm 2, stderrtil den samme destination som strøm 1 stdoutomdirigeres til."

Der er ingen synlig output. Det er opmuntrende.

Lad os kontrollere capture.txt-filen og se, hvad der er i den.

cat capture.txt

Både streams stdoutog stderrstreams er omdirigeret til en enkelt destinationsfil.

For at få output fra en stream omdirigeret og lydløst kastet skal du rette output til /dev/null.

Registrering af omdirigering inden for et script

Vi diskuterede, hvordan en kommando kan registrere, om nogen af ​​streamene omdirigeres, og kan vælge at ændre dens adfærd i overensstemmelse hermed. Kan vi opnå dette i vores egne scripts? Ja vi kan. Og det er en meget let teknik at forstå og anvende.

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

#! / bin / bash hvis [-t 0]; derefter ekko stdin kommer fra tastaturet ellers ekko stdin kommer fra et rør eller en fil fi

Brug følgende kommando til at gøre den eksekverbar:

chmod + x input.sh

Den smarte del er testen inden for de firkantede parenteser. Indstillingen -t(terminal) returnerer true (0), hvis filen, der er knyttet til filbeskrivelsen, slutter i terminalvinduet. Vi har brugt filbeskrivelsen 0 som argumentet til testen, som repræsenterer   stdin.

Hvis stdiner tilsluttet et terminalvindue, vil testen vise sig at være sand. Hvis der stdiner tilsluttet en fil eller et rør, mislykkes testen.

Vi kan bruge enhver praktisk tekstfil til at generere input til scriptet. Her bruger vi en kaldet dummy.txt.

./input.sh <dummy.txt

Outputtet viser, at scriptet genkender, at input ikke kommer fra et tastatur, det kommer fra en fil. Hvis du vælger det, kan du ændre dit scripts adfærd i overensstemmelse hermed.

Det var med en filomdirigering, lad os prøve det med et rør.

cat dummy.txt | ./input.sh

Scriptet genkender, at dets input ledes ind i det. Eller mere præcist, det genkender endnu en gang, at stdinstrømmen ikke er forbundet til et terminalvindue.

Lad os køre scriptet med hverken rør eller omdirigeringer.

./input.sh

Den stdinstrøm er forbundet til terminalen vindue, og scriptet rapporterer dette i overensstemmelse hermed.

For at kontrollere det samme med outputstrømmen har vi brug for et nyt script. Skriv følgende i en editor og gem det som output.sh.

#! / bin / bash hvis [-t 1]; så går ekko stdout til terminalvinduet ellers omdirigeres ekko stdout eller pipes fi

Brug følgende kommando til at gøre den eksekverbar:

chmod + x input.sh

Den eneste væsentlige ændring af dette script er i testen i firkantede parenteser. Vi bruger ciffer 1 til at repræsentere filbeskrivelsen for stdout.

Lad os prøve det. Vi sender produktionen igennem cat.

./output | kat

Scriptet genkender, at dets output ikke går direkte til et terminalvindue.

Vi kan også teste scriptet ved at omdirigere output til en fil.

./output.sh> capture.txt

Der er ingen output til terminalvinduet, vi returneres lydløst til kommandoprompten. Som vi havde forventet.

Vi kan se inde i capture.txt-filen for at se, hvad der blev fanget. Brug følgende kommando til at gøre det.

cat capture.sh

Igen registrerer den enkle test i vores script, at stdoutstrømmen ikke sendes direkte til et terminalvindue.

Hvis vi kører scriptet uden nogen rør eller omdirigeringer, skal det registrere, at stdoutdet leveres direkte til terminalvinduet.

./output.sh

Og det er præcis, hvad vi ser.

Strømme af bevidsthed

At vide, hvordan man fortæller, om dine scripts er forbundet til terminalvinduet, eller et rør eller omdirigeres, giver dig mulighed for at justere deres adfærd i overensstemmelse hermed.

Logning og diagnostisk output kan være mere eller mindre detaljeret, afhængigt af om det går til skærmen eller til en fil. Fejlmeddelelser kan logges på en anden fil end den normale programoutput.

Som det normalt er tilfældet, giver mere viden flere muligheder.