Mis on stdin, stdout ja stderr Linuxis?
stdin
, stdout
ja stderr
on kolm andmevoogu, mis luuakse Linuxi käsu käivitamisel. Nende abil saate öelda, kas teie skripte edastatakse või suunatakse ümber. Me näitame teile, kuidas.
Vood liituvad kahe punktiga
Niipea kui hakkate Linuxi ja Unixi-laadsete operatsioonisüsteemide kohta tundma õppima, jõuate terminitega kokku stdin
, stdout
ja stederr
. Need on kolm standardset voogu, mis luuakse Linuxi käsu käivitamisel. Arvutamisel on voog midagi, mis võimaldab andmeid edastada. Nende voogude puhul on need andmed tekst.
Andmevoogudel, nagu ka veevoogudel, on kaks otsa. Neil on allikas ja väljavool. Ükskõik, millist Linuxi käsku te kasutate, tagab iga voo ühe otsa. Teise otsa määrab käsu käivitanud kest. See ots ühendatakse terminaliaknaga, ühendatakse toruga või suunatakse faili või muule käsule vastavalt käsu käivitanud käsureale.
Linuxi standardvood
Linuxisstdin
on standardne sisendvoog. See aktsepteerib teksti sisendina. Tekstiväljund käsust shellile edastatakse stdout
(standard välja) voog. Käsu tõrketeated saadetakse stderr
(standardviga) voog.
Nii näete, et on kaks väljundvoogu, stdout
ja stderr
ja üks sisendvoog, stdin
. Kuna veateadetel ja tavalisel väljundil on klemmiaknasse kandmiseks oma kanal, saab neid käsitseda üksteisest sõltumatult.
Voogusid käsitletakse nagu faile
Linuxi vooge - nagu peaaegu kõike muud - koheldakse nagu faile. Saate failist teksti lugeda ja teksti faili kirjutada. Mõlemad toimingud hõlmavad andmevoogu. Nii et andmevoo failina käsitlemise kontseptsioon pole nii suur venitus.
Igale protsessiga seotud failile määratakse selle tuvastamiseks kordumatu number. Seda nimetatakse faili kirjeldajaks. Kui faili jaoks on vaja toimingut teha, kasutatakse faili tuvastamiseks faili kirjeldajat.
Neid väärtusi kasutatakse alati stdin
, stdout,
ja stderr
:
- 0: stdin
- 1: stdout
- 2: stderr
Torudele ja ümbersuunamistele reageerimine
Kellegi ainega tutvustamise hõlbustamiseks on levinud tehnika teema lihtsustatud versiooni õpetamine. Näiteks grammatika puhul öeldakse meile, et reegel on “Mina enne E, välja arvatud pärast C.” Kuid tegelikult on sellest reeglist rohkem erandeid kui juhtumeid, mis seda täidavad.
Sarnases mõttes, kui rääkida stdin
, stdout
ja stderr
on mugav traavida aktsepteeritud aksioom, et protsess ei tea ega huvita, kus selle kolm standardset voogu lõpetatakse. Kas protsess peaks hoolima sellest, kas selle väljund läheb terminali või suunatakse faili? Kas ta suudab isegi öelda, kas selle sisend tuleb klaviatuurilt või sisestatakse seda mõne muu protsessi kaudu?
Tegelikult teab protsess - või vähemalt saab seda teada, kui ta peaks kontrollima - ja saab vastavalt oma käitumist muuta, kui tarkvara autor otsustas selle funktsiooni lisada.
Me näeme seda muutust käitumises väga lihtsalt. Proovige neid kahte käsku:
ls
ls | kass
The ls
käsk käitub teisiti, kui selle väljund (stdout
) sisestatakse teise käsu juurde. see onls
mis lülitub ühe veeru väljundiks, pole see konversioon, mille teostab kass
. Ja ls
teeb sama asja, kui selle väljundit suunatakse ümber:
ls> lüüa.txt
kassi püüdmine.txt
Stdouti ja stderri ümbersuunamine
Spetsiaalse voo kaudu on veateadete eeliseks. See tähendab, et saame käsu väljundi ümber suunata (stdout
) faili ja näete endiselt veateateid (stderr
) terminaliaknas. Vigadele saate vajadusel reageerida, kui need ilmnevad. Samuti peatab see tõrketeadete selle faili saastamise stdout
on ümber suunatud.
Sisestage järgmine tekst redaktorisse ja salvestage see faili nimega error.sh.
#! / bin / bash echo "Olemasolevale failile juurdepääsu proovimiseks" kass halb-failinimi.txt
Muutke skript selle käsuga käivitatavaks:
chmod + x error.sh
Skripti esimene rida kajas teksti terminaliaknassestdout
voog. Teine rida proovib juurde pääseda failile, mida pole olemas. See loob veateate, mis edastatakse kaudu stderr
.
Käivitage skript selle käsuga:
./error.sh
Näeme, et mõlemad väljundvood, stdout
ja stderr
on kuvatud terminaliakendes.
Proovime suunata väljund faili:
./error.sh> capture.txt
Kaudu edastatud veateade stderr
saadetakse ikka terminaliaknasse. Saame kontrollida faili sisu, et näha, kas stdout
väljund läks faili.
kassi püüdmine.txt
Väljund stdin
suunati faili vastavalt ootustele.
The >
ümbersuunamise sümbol töötab stdout
algselt. Ühe numbrilise failikirjeldaja abil saate näidata, millist standardset väljundvoogu soovite ümber suunata.
Selgesõnaliselt ümbersuunamiseks stdout
, kasutage seda ümbersuunamisjuhist:
1>
Selgesõnaliselt ümbersuunamiseks stderr
, kasutage seda ümbersuunamisjuhist:
2>
Proovime uuesti proovida ja seekord kasutame 2>
:
./error.sh 2> capture.txt
Veateade suunatakse ümber ja stdout
kaja
sõnum saadetakse terminaliaknasse:
Vaatame, mis on failis capture.txt.
kassi püüdmine.txt
The stderr
sõnum on ootuspäraselt capt.txt-s.
Nii stdout kui stderr ümbersuunamine
Kindlasti, kui suudame kumbagi ümber suunata stdout
või stderr
faili üksteisest sõltumatult, peaksime saama neid mõlemat korraga ümber suunata kahte erinevasse faili?
Jah me saame. See käsk suunab stdout
faili nimega capture.txt ja stderr
faili nimega error.txt.
./error.sh 1> capture.txt 2> error.txt
Kuna mõlemad väljundvood - standardväljund ja standardviga - suunatakse failidesse, pole terminaliaknas nähtavat väljundit. Me naaseme käsurea viipale, nagu poleks midagi juhtunud.
Kontrollime iga faili sisu:
kassi püüdmine.txt
kassi viga.txt
Stdouti ja stderri ümbersuunamine samasse faili
See on kena, meil on kõik tavalised väljundvood oma spetsiaalsesse faili. Ainus teine kombinatsioon, mida saame teha, on saata mõlemad stdout
ja stderr
samasse faili.
Selle saavutame järgmise käsuga:
./error.sh> capture.txt 2> & 1
Lahustame selle.
- ./error.sh: Käivitab skriptifaili error.sh.
- > lüüa.txt: Suunab
stdout
voog faili capture.txt.>
on lühikirjeldus1>
. - 2>&1: See kasutab käsku &> ümbersuunamine. See juhis võimaldab teil öelda kestale, et üks voog jõuaks teise vooga samasse sihtkohta. Sel juhul ütleme „suunake voog 2 ümber,
stderr
, samasse sihtkohta, mis voog 1,stdout
, suunatakse aadressile. "
Nähtavat väljundit pole. See on julgustav.
Kontrollime faili capture.txt ja näeme, mis selles on.
kassi püüdmine.txt
Mõlemad stdout
ja stderr
voogud on suunatud ühte sihtfaili.
Voo väljundi ümbersuunamiseks ja hääletuks viskamiseks suunake väljund / dev / null
.
Ümbersuunamise tuvastamine skripti sees
Arutasime, kuidas käsk suudab tuvastada, kas mõnda voogu suunatakse ümber, ja saame oma käitumist vastavalt muuta. Kas me saame seda oma skriptide abil saavutada? Jah me saame. Ja seda on väga lihtne mõista ja rakendada.
Sisestage järgmine tekst redaktorisse ja salvestage see sisendina.sh.
#! / bin / bash kui [-t 0]; siis klaviatuurilt tulev kaja-stdin mujalt torust või faili-fi-st tulev kaja-stdin
Selle käivitamiseks kasutage järgmist käsku:
chmod + x sisend.sh
Nutikas osa on katse nurksulgudes. The -t
(terminal) tagastab väärtuse true (0), kui failikirjeldajaga seotud fail lõpeb terminaliaknas. Testi argumendina kasutasime faili kirjeldajat 0, mis esindabstdin
.
Kui stdin
on terminali aknaga ühendatud, osutub test tõeseks. Kui stdin
on faili või toruga ühendatud, test ebaõnnestub.
Skripti sisendi loomiseks võime kasutada mis tahes mugavat tekstifaili. Siin kasutame ühte nime dummy.txt.
./input.sh <näiv.txt
Väljund näitab, et skript tuvastab, et sisend ei pärine klaviatuurilt, vaid failist. Kui otsustate, võite vastavalt oma skripti käitumist muuta.
See oli faili ümbersuunamisega, proovime seda toruga.
kass mannekeen.txt | ./input.sh
Skript tunnistab, et sinna sisestatakse selle sisend. Või täpsemalt, ta tunnistab veel kord, et stdin
voog pole terminaliaknaga ühendatud.
Käivitame skripti ilma torude ega ümbersuunamisteta.
./input.sh
The stdin
voog on ühendatud terminaliaknaga ja skript teatab sellest vastavalt.
Sama asja kontrollimiseks väljundvooga vajame uut skripti. Sisestage redaktorisse järgmine ja salvestage see väljundina.sh.
#! / bin / bash kui [-t 1]; siis läheb kaja stdout terminaliaknasse, muidu suunatakse kaja stdout ümber või torustatakse fi
Selle käivitamiseks kasutage järgmist käsku:
chmod + x sisend.sh
Ainus oluline muudatus selles skriptis on nurksulgudes olev test. Kasutame faili kirjeldaja tähistamiseks numbrit 1 stdout
.
Proovime järele. Me juhime väljundi läbi kass
.
./väljund | kass
Skript tunnistab, et selle väljund ei lähe otse terminaliaknasse.
Samuti saame skripti testida, suunates väljundi faili.
./output.sh> capture.txt
Terminali aknas pole väljundit, meid naastakse vaikides käsureale. Nagu me eeldaksime.
Saame vaadata faili capture.txt sisse, et näha, mis on jäädvustatud. Selleks kasutage järgmist käsku.
kassi püüdmine.sh
Jällegi tuvastab meie skripti lihtne test, et stdout
voogu ei saadeta otse terminaliaknasse.
Kui käivitame skripti ilma torude või ümbersuunamisteta, peaks see selle tuvastama stdout
tarnitakse otse terminaliaknasse.
./output.sh
Ja seda me täpselt näeme.
Teadvusevood
Teadmine, kuidas teada saada, kas teie skriptid on terminali akna või toruga ühendatud või suunatakse ümber, võimaldab teil nende käitumist vastavalt kohandada.
Logi ja diagnostika väljund võib olla enam-vähem üksikasjalik, olenevalt sellest, kas see läheb ekraanile või faili. Veateateid saab logida muusse faili kui tavaline programmi väljund.
Nagu tavaliselt, annab rohkem teadmisi rohkem võimalusi.