Kas yra „stdin“, „stdout“ ir „stderr“ sistemoje „Linux“?

stdin, stdoutir stderryra trys duomenų srautai, sukurti paleidus „Linux“ komandą. Jais galite sužinoti, ar jūsų scenarijai siunčiami ar peradresuojami. Mes parodome, kaip.

Srautai sujungia du taškus

Kuo greičiau pradėti mokytis apie Linux ir Unix operacinių sistemų, jums ateis visoje terminų stdin, stdoutir stederr. Tai yra trys standartiniai srautai, kurie nustatomi vykdant „Linux“ komandą. Skaičiuojant srautas gali perduoti duomenis. Šių srautų atveju šie duomenys yra tekstas.

Duomenų srautai, kaip ir vandens srautai, turi du galus. Jie turi šaltinį ir nutekėjimą. Nesvarbu, kurią „Linux“ komandą naudojate, pateikiamas vienas kiekvieno srauto galas. Kitą galą nustato apvalkalas, paleidęs komandą. Tas galas bus prijungtas prie terminalo lango, prijungtas prie vamzdžio arba nukreiptas į failą ar kitą komandą pagal komandą, paleidusią komandą.

„Linux“ standartiniai srautai

„Linux“  stdinyra standartinis įvesties srautas. Tai priima tekstą kaip įvestį. Teksto išvestis iš komandos į apvalkalą pateikiama per stdout(standartinio išėjimo) srautą. Klaidos pranešimai iš komandos siunčiami per stderr(standartinės klaidos) srautą.

Taigi galite pamatyti, kad yra du išvesties srautai stdoutir stderr, ir vienas įvesties srautas stdin,. Kadangi klaidų pranešimai ir įprasta išvestis turi savo kanalą, perkeliantį juos į terminalo langą, juos galima tvarkyti nepriklausomai vienas nuo kito.

Srautai tvarkomi kaip failai

„Linux“ srautai, kaip ir beveik visa kita, traktuojami taip, lyg jie būtų failai. Galite skaityti tekstą iš failo ir galite rašyti tekstą į failą. Abu šie veiksmai apima duomenų srautą. Taigi duomenų srauto kaip failo tvarkymo koncepcija nėra tokia ilga.

Kiekvienam failui, susietam su procesu, priskiriamas unikalus numeris, kuris jį identifikuoja. Tai vadinama failo deskriptoriumi. Kai failui reikia atlikti veiksmą, failui identifikuoti naudojamas failo aprašas.

Šios vertybės yra visada naudojamas stdin, stdout,ir stderr:

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

Reagavimas į vamzdžius ir peradresavimus

Siekiant palengvinti kieno nors įvadą į dalyką, įprasta technika yra mokyti supaprastintą temos variantą. Pavyzdžiui, kalbant gramatika, mums sakoma, kad taisyklė yra „Aš prieš E, išskyrus po C.“ Tačiau iš tikrųjų yra daugiau šios taisyklės išimčių nei atvejų, kai jos laikomasi.

Panašiai, kalbant apie stdin, stdoutir stderr patogu išaiškinti priimtą aksiomą, kad procesas nei žino, nei rūpinasi, kur baigiasi trys jo standartiniai srautai. Ar procesui turėtų būti svarbu, ar jo išvestis eina į terminalą, ar nukreipiama į failą? Ar ji netgi gali pasakyti, ar jo įvestis gaunama iš klaviatūros, ar į ją įvedamas iš kito proceso?

Tiesą sakant, procesas tikrai žino - ar bent jau gali sužinoti, jei pasirenka patikrinti - ir gali atitinkamai pakeisti savo elgesį, jei programinės įrangos autorius nusprendė pridėti šią funkciją.

Šį elgesio pokytį galime pamatyti labai lengvai. Išbandykite šias dvi komandas:

ls

ls | katė

Į lskomandų elgiasi skirtingai, jei jos produkcija ( stdout) yra vamzdynais tiekiamas į kitą komandą. Būtent tai  lsperjungiama į vieno stulpelio išvestį, tai nėra konversija, kurią atlieka cat. Ir lsdaro tą patį, jei jo išvestis yra peradresuojama:

ls> capture.txt

katės gaudymas.txt

Peradresuojama stdout ir stderr

Yra pranašumas, kai klaidų pranešimus pateikia specialus srautas. Tai reiškia, kad galime nukreipti komandos išvestį ( stdout) į failą ir vis tiek matyti bet kokius klaidų pranešimus ( stderr) terminalo lange. Jei reikia, galite reaguoti į klaidas. Tai taip pat sustabdo klaidų pranešimus užteršti failą, stdoutkuris buvo nukreiptas.

Įveskite šį tekstą į redaktorių ir išsaugokite jį faile, vadinamame error.sh.

#! / bin / bash echo „Apie bandymą pasiekti neegzistuojantį failą“ katė blogai-filename.txt

Padarykite scenarijų vykdomąjį naudodami šią komandą:

chmod + x error.sh

Pirmoji scenarijaus eilutė atkartoja tekstą į terminalo langą per  stdoutsrautą. Antroje eilutėje bandoma pasiekti failą, kurio nėra. Tai sukurs klaidos pranešimą, kuris bus pateiktas per stderr.

Paleiskite scenarijų naudodami šią komandą:

./klaida.sh

Mes galime pamatyti, kad abu išvesties srautai stdoutir stderrrodomi terminalo languose.

Pabandykime nukreipti išvestį į failą:

./error.sh> capture.txt

Klaidos pranešimas, kuris yra pateiktas per stderr, vis tiek siunčiamas į terminalo langą. Galime patikrinti failo turinį, kad sužinotume, ar stdout išvestis atiteko failui.

katės gaudymas.txt

Išvestis iš stdinfailo buvo peradresuota, kaip tikėtasi.

>Nukreipimas simbolis dirba su stdoutpagal nutylėjimą. Norėdami nurodyti, kurį standartinį išvesties srautą norite peradresuoti, galite naudoti vieną iš skaitinių failų aprašų.

Norėdami aiškiai peradresuoti  stdout, naudokite šią peradresavimo instrukciją:

1>

Norėdami aiškiai peradresuoti  stderr, naudokite šią peradresavimo instrukciją:

2>

Pabandykime dar kartą išbandyti ir šį kartą naudosime 2>:

./error.sh 2> capture.txt

Klaidos pranešimas nukreipiamas ir stdoutechopranešimas siunčiamas į terminalo langą:

Pažiūrėkime, kas yra faile capt.txt.

katės gaudymas.txt

stderrŽinutė yra capture.txt kaip tikėtasi.

Peradresuojama ir stdout, ir stderr

Be abejo, jei galime peradresuoti vieną stdoutar stderrkitą failą nepriklausomai vienas nuo kito, turėtume sugebėti juos abu peradresuoti vienu metu į du skirtingus failus?

Taip, mes galime. Ši komanda bus nukreipta stdoutį stderrfailą, pavadintą capture.txt, ir į failą, pavadintą error.txt.

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

Kadangi tiek išvesties srautai - standartinė išvestis, tiek standartinė klaida - yra nukreipiami į failus, terminalo lange nėra matomos išvesties. Grįžtame į komandinės eilutės eilutę, tarsi nieko neįvyko.

Patikrinkime kiekvieno failo turinį:

katės gaudymas.txt
katės klaida.txt

Nukreipiant „stdout“ ir „stderr“ į tą patį failą

Tai tvarkinga, kiekvienas standartinis išvesties srautas patenka į savo atskirą failą. Vienintelis kitas derinys, mes galime padaryti, tai atsiųsti tiek stdoutir stderrį tą patį failą.

Tai galime pasiekti naudodami šią komandą:

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

Sugrupuokime tai.

  • ./error.sh : Paleidžiamas failas error.sh.
  • > capture.txt : nukreipia stdoutsrautą į failą capture.txt. >yra trumpinys 1>.
  • 2> & 1 : Tam naudojama peradresavimo instrukcija. Ši instrukcija leidžia jums pasakyti apvalkalui, kad vienas srautas patektų į tą patį tikslą kaip ir kitas srautas. Šiuo atveju sakome, kad „2 srautas peradresuojamas stderrį tą pačią paskirties vietą, į kurią nukreipiamas 1 srautas stdout“.

Nėra matomos išvesties. Tai skatina.

Patikrinkime failą capt.txt ir pažiūrėkime, kas jame yra.

katės gaudymas.txt

Tiek stdoutir stderrsrautai buvo nukreipti į vieną paskirties failą.

Norėdami, kad srauto išvestis būtų nukreipta ir tyliai išmesta, nukreipkite išvestį į /dev/null.

Peradresavimo aptikimas scenarijuje

Aptarėme, kaip komanda gali aptikti, ar kuris nors srautas yra peradresuojamas, ir galime atitinkamai pakeisti savo elgesį. Ar galime tai pasiekti savo scenarijais? Taip, mes galime. Tai labai lengva suprasti ir pritaikyti.

Įveskite šį tekstą į redaktorių ir išsaugokite jį kaip input.sh.

#! / bin / bash jei [-t 0]; tada echo stdin, gaunamas iš klaviatūros, kitas echo stdin, gaunamas iš pypkės ar failo fi

Naudokite šią komandą, kad ji būtų vykdoma:

chmod + x įvestis.sh

Protinga dalis yra testas laužtiniuose skliaustuose. Parinktis -t(terminalas) grąžina true (0), jei terminalo lange baigiasi failas, susietas su failo deskriptoriumi. Mes naudojome failo deskriptorių 0 kaip argumentą bandymui, kuris rodo   stdin.

Jei stdinbandymas bus prijungtas prie terminalo lango, tai bus teisinga. Jei stdinjis prijungtas prie failo ar vamzdžio, bandymas nepavyks.

Norėdami sukurti įvestį į scenarijų, galime naudoti bet kokį patogų tekstinį failą. Čia mes naudojame vieną, vadinamą „dummy.txt“.

./input.sh <manekenas.txt

Išvestis rodo, kad scenarijus atpažįsta, kad įvestis gaunama ne iš klaviatūros, o iš failo. Jei pasirinktumėte, galėtumėte atitinkamai keisti scenarijaus elgesį.

Tai buvo su failo peradresavimu, pabandykime tai vamzdžiu.

katės manekenas.txt | ./input.sh

Scenarijus atpažįsta, kad į jį įvedamas jo įvestis. Arba tiksliau, jis dar kartą pripažįsta, kad stdinsrautas nėra prijungtas prie terminalo lango.

Vykdykime scenarijų be vamzdžių ir peradresavimų.

./input.sh

stdinSrautas yra prijungtas prie terminalo langą, o scenarijų pranešimų šiame pakeisti.

Norėdami patikrinti tą patį dalyką su išvesties srautu, mums reikia naujo scenarijaus. Į redaktorių įveskite šiuos duomenis ir išsaugokite juos kaip output.sh.

#! / bin / bash jei [-t 1]; tada echo stdout eina į terminalo langą, kitas echo stdout yra nukreipiamas arba perduodamas fi

Naudokite šią komandą, kad ji būtų vykdoma:

chmod + x įvestis.sh

Vienintelis reikšmingas šio scenarijaus pakeitimas yra testas laužtiniuose skliaustuose. Failo deskriptoriui apibūdinti naudojame 1 skaitmenį stdout.

Išbandykime. Perduosime išvestį cat.

./output | katė

Scenarijus atpažįsta, kad jo išvestis nėra tiesiogiai nukreipiama į terminalo langą.

Taip pat galime patikrinti scenarijų, nukreipdami išvestį į failą.

./output.sh> capture.txt

Į terminalo langą nėra išvesties, mes tyliai grįšime į komandų eilutę. Kaip ir tikėjomės.

Mes galime pažvelgti į failą capt.txt ir pamatyti, kas buvo užfiksuota. Norėdami tai padaryti, naudokite šią komandą.

kačių gaudymas.sh

Vėlgi, paprastas mūsų scenarijaus testas nustato, kad stdoutsrautas nėra siunčiamas tiesiai į terminalo langą.

Jei vykdysime scenarijų be jokių vamzdžių ar peradresavimų, jis turėtų aptikti, kad stdoutjis pristatomas tiesiai į terminalo langą.

./output.sh

Ir mes būtent tai matome.

Sąmonės srautai

Žinodami, kaip sužinoti, ar scenarijai yra prijungti prie terminalo lango, ar su vamzdžiu, ar yra nukreipiami, galite atitinkamai pakoreguoti jų elgesį.

Registravimo ir diagnostikos išvestis gali būti daugiau ar mažiau išsami, atsižvelgiant į tai, ar ji eis į ekraną, ar į failą. Klaidų pranešimus galima užregistruoti kitame faile nei įprasta programos išvestis.

Kaip paprastai būna, daugiau žinių suteikia daugiau galimybių.