Mitä ovat stdin, stdout ja stderr Linuxissa?

stdin
, stdout
ja stderr
ovat 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
, stdout
ja 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 stdin
on tavallinen tulovirta. Tämä hyväksyy tekstin syötteeksi. Tekstilähtö komennosta komentotulkkiin toimitetaan stdout
(vakioulostulo) -virran kautta. Komennon stderr
virheilmoitukset lähetetään (vakiovirhe) -virran kautta.
Voit siis nähdä, että on olemassa kaksi tuotevirtojen, stdout
ja 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
, stdout
ja 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
ls
Komento käyttäytyy eri tavalla, jos sen ulostulo ( stdout
) on johdetaan toiseen komento. Se ls
vaihtaa yhden sarakkeen ulostuloksi, se ei ole muunnos, jonka suorittaa cat
. Ja ls
tekee 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 stdout
virran 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 stdout
ja stderr
ovat näkyneet pääteikkunoissa.
Yritetään ohjata ulostulo tiedostoon:
./error.sh> capture.txt
Virheilmoitus, joka toimitetaan kautta, stderr
lä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 stdin
ohjataan tiedostoon odotusten mukaisesti.
Uudelleenohjaussymboli >
toimii stdout
oletuksena. Voit käyttää yhtä numeerisista tiedostokuvaajista osoittamaan, minkä vakiolähtövirran haluat ohjata.
Käytä nimenomaista uudelleenohjausta stdout
käyttämällä tätä uudelleenohjausohjetta:
1>
Käytä nimenomaista uudelleenohjausta stderr
kä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 stdout
echo
viesti lähetetään pääteikkunaan:
Katsotaanpa, mikä on capture.txt-tiedostossa.
kissan sieppaus.txt
stderr
Viesti on capture.txt odotetusti.
Uudelleenohjataan sekä stdout että stderr
Varmasti, jos voimme ohjata jommankumman stdout
tai stderr
tiedostoon toisistaan riippumatta, meidän pitäisi pystyä ohjaamaan ne molemmat samanaikaisesti kahteen eri tiedostoon?
Kyllä me voimme. Tämä komento ohjaa stdout
tiedostoon nimeltä capture.txt ja stderr
tiedostoon 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 stdout
ja stderr
samaan 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
stdout
virran capture.txt-tiedostoon.>
on lyhyt1>
. - 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
stderr
samaan määränpäähän, johon virta 1stdout
lähetetään."
Näkyvää lähtöä ei ole. Se on rohkaisevaa.
Tarkistetaan capture.txt-tiedosto ja katsotaan, mitä siinä on.
kissan sieppaus.txt
Sekä stdout
ja stderr
virrat 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 stdin
testi on kytketty pääteikkunaan, testi osoittautuu totta. Jos se stdin
on 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ä stdin
virta ei ole kytketty pääteikkunaan.
Suoritetaan komentosarja ilman putkia eikä uudelleenohjauksia.
./input.sh
stdin
Virta 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ä stdout
virtaa ei lähetetä suoraan pääteikkunaan.
Jos suoritamme komentosarjan ilman putkia tai uudelleenohjauksia, sen pitäisi havaita, että stdout
se 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.