Mitä ovat stdin, stdout ja stderr Linuxissa?

stdin, stdoutja stderrovat kolme tietovirtaa, jotka luodaan, kun käynnistät Linux-komennon. Voit selvittää niiden avulla, komentosarjojasi lähetetäänkö tai ohjataan uudelleen. Näytämme sinulle miten.

Virrat yhdistävät kaksi pistettä

Heti kun alat oppia Linux ja Unix-käyttöjärjestelmille, sinun törmännyt termejä stdin, stdoutja stederr. Nämä ovat kolme vakiovirtaa, jotka muodostetaan, kun Linux-komento suoritetaan. Laskennassa virta on jotain, joka voi siirtää tietoja. Näiden virtojen tapauksessa kyseiset tiedot ovat tekstiä.

Tietovirroilla, kuten vesivirroilla, on kaksi päätä. Heillä on lähde ja ulosvirtaus. Kumpi tahansa käyttämäsi Linux-komento tarjoaa jokaisen virran toisen pään. Toinen pää määräytyy komennon käynnistäneen kuoren mukaan. Tämä pää liitetään pääteikkunaan, liitetään putkeen tai ohjataan tiedostoon tai muuhun komentoon komennon käynnistäneen komentorivin mukaisesti.

Linux-standardivirrat

Linuxissa  stdinon tavallinen tulovirta. Tämä hyväksyy tekstin syötteeksi. Tekstilähtö komennosta komentotulkkiin toimitetaan stdout(vakioulostulo) -virran kautta. Komennon stderrvirheilmoitukset lähetetään (vakiovirhe) -virran kautta.

Voit siis nähdä, että on olemassa kaksi tuotevirtojen, stdoutja stderr, ja yksi Syötevirran stdin. Koska virheilmoituksilla ja normaalilla ulostulolla on kullakin oma kanava niiden kuljettamiseksi pääteikkunaan, niitä voidaan käsitellä toisistaan ​​riippumatta.

Suoratoistoja käsitellään kuten tiedostoja

Linux-virtoja - kuten melkein kaikkea muuta - käsitellään ikään kuin ne olisivat tiedostoja. Voit lukea tekstiä tiedostosta ja kirjoittaa tekstiä tiedostoon. Molemmat näistä toiminnoista sisältävät tietovirran. Joten tietovirran käsitteleminen tiedostona ei ole niin suuri venytys.

Jokaiselle prosessiin liittyvälle tiedostolle annetaan yksilöivä numero sen tunnistamiseksi. Tätä kutsutaan tiedostokuvaajaksi. Aina kun tiedostolle on suoritettava jokin toiminto, tiedoston tunnistamiseen käytetään tiedostokuvainta.

Näitä arvoja käytetään aina stdin, stdout,ja stderr:

  • 0 : stdin
  • 1 : vakio
  • 2 : stderr

Reagointi putkiin ja uudelleenohjauksiin

Aiheen käyttöönoton helpottamiseksi yleinen tekniikka on opettaa yksinkertaistettu versio aiheesta. Esimerkiksi kieliopin kanssa meille kerrotaan, että sääntö on "minä ennen E, paitsi C: n jälkeen". Mutta todellisuudessa tästä säännöstä on enemmän poikkeuksia kuin on tapauksia, jotka noudattavat sitä.

Samaan tapaan, kun puhutaan stdin, stdoutja stderr se on kätevä ottaa esille hyväksytyistä selviö, että prosessi eikä tunne eikä huolet kun sen kolme standardia virtoja lopetetaan. Pitäisikö prosessista huolehtia siitä, meneekö sen lähtö päätelaitteeseen vai ohjataako se uudelleen tiedostoon? Voiko se edes kertoa, tuleeko sen syöttö näppäimistöltä vai syötetäänkö sitä toiseen prosessista?

Itse asiassa prosessi tietää - tai ainakin se voi saada selville, jos se haluaa tarkistaa - ja voi muuttaa käyttäytymistään vastaavasti, jos ohjelmiston tekijä on päättänyt lisätä kyseisen toiminnon.

Voimme nähdä tämän muutoksen käyttäytymisessä hyvin helposti. Kokeile näitä kahta komentoa:

Ls

ls | kissa

lsKomento käyttäytyy eri tavalla, jos sen ulostulo ( stdout) on johdetaan toiseen komento. Se  lsvaihtaa yhden sarakkeen ulostuloksi, se ei ole muunnos, jonka suorittaa cat. Ja lstekee saman, jos sen lähtöä ohjataan uudelleen:

ls> sieppaa.txt

kissan sieppaus.txt

Uudelleenohjataan stdout ja stderr

On etuna, että virheilmoitukset toimitetaan erillisellä virralla. Se tarkoittaa, että voimme ohjata komennon lähdön ( stdout) tiedostoon ja silti nähdä virheilmoitukset ( stderr) pääteikkunassa. Voit reagoida virheisiin tarvittaessa, koska ne tapahtuvat. Se myös estää virheilmoituksia saastuttamasta uudelleenohjaettua tiedostoa stdout.

Kirjoita seuraava teksti editoriin ja tallenna se tiedostoon nimeltä error.sh.

#! / bin / bash echo "Yritän käyttää tiedostoa, jota ei ole olemassa" cat bad-filename.txt

Tee komentosarja suoritettavaksi tällä komennolla:

chmod + x virhe.sh

Komentosarjan ensimmäinen rivi toistaa tekstiä pääteikkunaan stdoutvirran kautta  . Toinen rivi yrittää käyttää tiedostoa, jota ei ole olemassa. Tämä luo virheilmoituksen, joka toimitetaan kautta stderr.

Suorita komentosarja tällä komennolla:

./error.sh

Voimme nähdä, että molemmat ulostulovirrat stdoutja stderrovat näkyneet pääteikkunoissa.

Yritetään ohjata ulostulo tiedostoon:

./error.sh> capture.txt

Virheilmoitus, joka toimitetaan kautta, stderrlähetetään edelleen pääteikkunaan. Voimme tarkistaa tiedoston sisällön nähdäksesi, menikö stdout lähtö tiedostoon.

kissan sieppaus.txt

Lähtö kohteesta stdinohjataan tiedostoon odotusten mukaisesti.

Uudelleenohjaussymboli >toimii stdoutoletuksena. Voit käyttää yhtä numeerisista tiedostokuvaajista osoittamaan, minkä vakiolähtövirran haluat ohjata.

Käytä nimenomaista uudelleenohjausta  stdoutkäyttämällä tätä uudelleenohjausohjetta:

1>

Käytä nimenomaista uudelleenohjausta  stderrkäyttämällä tätä uudelleenohjausohjetta:

2>

Yritetään testata uudelleen, ja tällä kertaa käytämme 2>:

./error.sh 2> capture.txt

Virhesanoma ohjataan uudelleen ja stdoutechoviesti lähetetään pääteikkunaan:

Katsotaanpa, mikä on capture.txt-tiedostossa.

kissan sieppaus.txt

stderrViesti on capture.txt odotetusti.

Uudelleenohjataan sekä stdout että stderr

Varmasti, jos voimme ohjata jommankumman stdouttai stderrtiedostoon toisistaan ​​riippumatta, meidän pitäisi pystyä ohjaamaan ne molemmat samanaikaisesti kahteen eri tiedostoon?

Kyllä me voimme. Tämä komento ohjaa stdouttiedostoon nimeltä capture.txt ja stderrtiedostoon nimeltä error.txt.

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

Koska molemmat ulostulovirrat - vakiolähtö ja vakiovirhe - ohjataan tiedostoihin, pääteikkunassa ei ole näkyvää ulostuloa. Palataan komentorivikehotteeseen ikään kuin mitään ei olisi tapahtunut.

Tarkistetaan jokaisen tiedoston sisältö:

kissan sieppaus.txt
kissa virhe.txt

Uudelleenohjataan stdout ja stderr samaan tiedostoon

Se on siisti, meillä kaikilla tavallisilla lähtövirroilla on oma oma tiedosto. Ainoa toinen yhdistelmä, jonka voimme tehdä, on lähettää molemmat stdoutja stderrsamaan tiedostoon.

Voimme saavuttaa tämän seuraavalla komennolla:

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

Hajotetaan se.

  • ./error.sh : Käynnistää error.sh-komentotiedoston.
  • > capture.txt : Ohjaa stdoutvirran capture.txt-tiedostoon. >on lyhyt 1>.
  • 2> & 1 : Tämä käyttää &> uudelleenohjauskäskyä. Tämän ohjeen avulla voit kertoa kuorelle, että yksi virta saapuu samaan määränpäähän kuin toinen virta. Tässä tapauksessa sanomme "ohjataan virta 2 uudelleen stderrsamaan määränpäähän, johon virta 1 stdoutlähetetään."

Näkyvää lähtöä ei ole. Se on rohkaisevaa.

Tarkistetaan capture.txt-tiedosto ja katsotaan, mitä siinä on.

kissan sieppaus.txt

Sekä stdoutja stderrvirrat on ohjattu yhdelle vastaanottajalle tiedostoon.

Suorita ulostulo osoitteeseen, jotta virta voidaan ohjata ja heittää pois äänettömästi /dev/null.

Ohjauksen havaitseminen komentosarjassa

Keskustelimme siitä, kuinka komento pystyy havaitsemaan, ohjaako jokin virroista uudelleen, ja voimme muuttaa sen käyttäytymistä vastaavasti. Voimmeko saavuttaa tämän omilla käsikirjoituksillamme? Kyllä me voimme. Ja se on erittäin helppo tekniikka ymmärtää ja käyttää.

Kirjoita seuraava teksti editoriin ja tallenna se input.sh-tiedostona.

#! / bin / bash jos [-t 0]; sitten näppäimistöltä tuleva kaiun stdin, muut putkesta tai tiedostosta fi tulevat kaiun stdin

Tee se suoritettavaksi seuraavalla komennolla:

chmod + x input.sh

Älykäs osa on testi hakasulkeissa. Vaihtoehto -t(pääte) palauttaa arvon true (0), jos tiedostokuvaimeen liittyvä tiedosto päättyy pääteikkunaan. Olemme käyttäneet tiedoston kuvainta 0 argumenttina testissä, joka edustaa   stdin.

Jos stdintesti on kytketty pääteikkunaan, testi osoittautuu totta. Jos se stdinon liitetty tiedostoon tai putkeen, testi epäonnistuu.

Voimme käyttää mitä tahansa kätevää tekstitiedostoa syöttääksesi komentosarjaan. Tässä käytämme yhtä nimeltään dummy.txt.

./input.sh <nuken.txt

Tulos osoittaa, että komentosarja tunnistaa, että tulo ei tule näppäimistöltä, se tulee tiedostosta. Jos valitset, voit muuttaa skriptisi käyttäytymistä vastaavasti.

Se tapahtui tiedoston uudelleenohjauksella, kokeillaan sitä putkella.

kissan nuken.txt | ./input.sh

Skripti tunnistaa, että sen syötettä syötetään siihen. Tai tarkemmin sanottuna se tunnistaa jälleen, että stdinvirta ei ole kytketty pääteikkunaan.

Suoritetaan komentosarja ilman putkia eikä uudelleenohjauksia.

./input.sh

stdinVirta on kytketty terminaali-ikkuna, ja käsikirjoitus raportoi tämän mukaisesti.

Tarvitsemme uuden komentosarjan, jotta voimme tarkistaa saman asian lähtövirralla. Kirjoita seuraava editoriin ja tallenna se output.sh-tiedostona.

#! / bin / bash jos [-t 1]; sitten echo stdout menee pääteikkunaan muuten echo stdout ohjataan tai putketaan fi

Tee se suoritettavaksi seuraavalla komennolla:

chmod + x input.sh

Ainoa merkittävä muutos tähän komentosarjaan on testi hakasulkeissa. Käytämme numeroa 1 edustamaan tiedoston kuvaajaa stdout.

Kokeillaan sitä. Tulemme putken läpi cat.

./lähtö | kissa

Skripti tunnistaa, että sen lähtö ei mene suoraan pääteikkunaan.

Voimme myös testata komentosarjan ohjaamalla lähdön tiedostoon.

./output.sh> capture.txt

Pääteikkunaan ei ole lähtöä, palataan hiljaa komentokehotteeseen. Kuten odotimme.

Voimme katsoa capture.txt-tiedoston sisälle nähdäksesi, mikä siepattiin. Käytä sitä seuraavalla komennolla.

kissan sieppaus.sh

Jälleen komentosarjamme yksinkertainen testi havaitsee, että stdoutvirtaa ei lähetetä suoraan pääteikkunaan.

Jos suoritamme komentosarjan ilman putkia tai uudelleenohjauksia, sen pitäisi havaita, että stdoutse toimitetaan suoraan pääteikkunaan.

./output.sh

Ja juuri näemme.

Tietoisuuden virrat

Tietäen kuinka selvittää, ovatko komentosarjat liitetty pääteikkunaan tai putkeen, vai ohjataanko ne uudelleen, voit säätää niiden käyttäytymistä vastaavasti.

Kirjaaminen ja diagnostiikkalähtö voivat olla enemmän tai vähemmän yksityiskohtaisia, riippuen siitä, meneekö se näyttöön vai tiedostoon. Virheilmoitukset voidaan kirjata eri tiedostoon kuin tavallinen ohjelmalähtö.

Kuten yleensä, enemmän tietoa tuo enemmän vaihtoehtoja.