Ano ang stdin, stdout, at stderr sa Linux?

si stdin, stdout, at stderr ay nilikha ang tatlong mga stream ng data kapag naglulunsad ka ng isang utos sa Linux. Maaari mong gamitin ang mga ito upang sabihin kung ang iyong mga script ay pipina o nai-redirect. Ipinapakita namin sa iyo kung paano.

Mga Stream Sumali sa Dalawang Mga Punto

Sa sandaling magsimula kang malaman tungkol sa mga operating system na tulad ng Linux at Unix, mahahanap mo ang mga tuntunin si stdin, stdout, at stederr. Ito ang tatlong pamantayang mga stream na naitatag kapag ang isang utos ng Linux ay naisakatuparan. Sa computing, ang isang stream ay isang bagay na maaaring maglipat ng data. Sa kaso ng mga stream na ito, ang data na iyon ay teksto.

Ang mga data stream, tulad ng mga stream ng tubig, ay may dalawang dulo. Mayroon silang mapagkukunan at isang pag-agos. Alinmang utos ng Linux na ginagamit mo ang nagbibigay ng isang dulo ng bawat stream. Ang kabilang dulo ay natutukoy ng shell na naglunsad ng utos. Ang pagtatapos na iyon ay kokonekta sa window ng terminal, konektado sa isang tubo, o mai-redirect sa isang file o iba pang utos, alinsunod sa linya ng utos na naglunsad ng utos.

Ang Linux Standard Streams

Sa Linux,si stdin ay ang karaniwang stream ng input. Tumatanggap ito ng teksto bilang input nito. Ang output ng teksto mula sa utos patungo sa shell ay naihatid sa pamamagitan ng stdout (standard out) stream. Ang mga mensahe ng error mula sa utos ay ipinapadala sa pamamagitan ng stderr (karaniwang error) stream.

Kaya makikita mo na mayroong dalawang output stream, stdout at stderr, at isang input stream, si stdin. Dahil ang mga mensahe ng error at normal na output bawat isa ay may kani-kanilang mga kanal upang dalhin ang mga ito sa window ng terminal, maaari silang hawakan nang nakapag-iisa sa isa't isa.

Hawakang Tulad ng Mga File ang Mga Stream

Ang mga stream sa Linux — tulad ng halos lahat ng bagay — ay itinuturing na sila ay mga file. Maaari mong basahin ang teksto mula sa isang file, at maaari kang magsulat ng teksto sa isang file. Ang parehong mga pagkilos na ito ay nagsasangkot ng isang stream ng data. Kaya't ang konsepto ng paghawak ng isang stream ng data bilang isang file ay hindi gaanong nakakaunat.

Ang bawat file na nauugnay sa isang proseso ay inilalaan ng isang natatanging numero upang makilala ito. Kilala ito bilang tagapaglarawan ng file. Tuwing kinakailangan ang isang pagkilos upang maisagawa sa isang file, ginagamit ang deskriptor ng file upang makilala ang file.

Ang mga halagang ito ay palaging ginagamit para sa si stdin, stdout, at stderr:

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

Reacting sa Mga Pipe at Pag-redirect

Upang mapagaan ang pagpapakilala ng isang tao sa isang paksa, isang pangkaraniwang pamamaraan ay magturo ng isang pinasimple na bersyon ng paksa. Halimbawa, sa gramatika, sinabi sa atin na ang panuntunan ay "Ako bago ang E, maliban pagkatapos ng C." Ngunit sa totoo lang, maraming mga pagbubukod sa panuntunang ito kaysa sa mga kaso na sumusunod dito.

Sa isang katulad na ugat, kapag pinag-uusapan si stdin, stdout, at stderr maginhawa upang mapalabas ang tinatanggap na axiom na ang isang proseso ay hindi nakakaalam o nagmamalasakit kung saan natapos ang tatlong pamantayang daloy nito. Dapat bang mag-ingat ang isang proseso kung ang output nito ay pupunta sa terminal o nai-redirect sa isang file? Maaari rin bang sabihin kung ang input nito ay nagmumula sa keyboard o pinapasok dito mula sa ibang proseso?

Sa totoo lang, alam ng isang proseso — o kahit papaano malalaman nito, dapat itong pumili upang suriin — at mababago nito ang pag-uugali nang naaayon kung nagpasya ang may-akda ng software na idagdag ang pagpapaandar na iyon.

Madali nating makikita ang pagbabagong ito sa pag-uugali. Subukan ang dalawang utos na ito:

ls

ls | pusa

Ang ls iba ang kilos ng utos kung ang output nito (stdout) ay piping sa isa pang utos. Ito ayls lumipat iyon sa isang solong output ng haligi, hindi ito isang conversion na isinagawa ng pusa. At ls Ginagawa ang parehong bagay kung ang output nito ay nai-redirect:

ls> capture.txt

cat capture.txt

Pag-redirect ng stdout at stderr

Mayroong kalamangan sa pagkakaroon ng mga mensahe ng error na naihatid ng isang nakatuong stream. Nangangahulugan ito na maaari naming i-redirect ang output ng isang utos (stdout) sa isang file at nakikita pa rin ang anumang mga mensahe ng error (stderr) sa window ng terminal. Maaari kang tumugon sa mga error kung kailangan mo, dahil nangyari ito. Pinipigilan din nito ang mga mensahe ng error mula sa kontaminasyon ng file na stdout ay nai-redirect sa.

I-type ang sumusunod na teksto sa isang editor at i-save ito sa isang file na tinatawag na error.sh.

#! / bin / bash echo "Tungkol sa upang subukang mag-access ng isang file na walang" cat bad-filename.txt

Gawin ang script na maipapatupad sa utos na ito:

chmod + x error.sh

Ang unang linya ng script ay umalingawngaw ng teksto sa window ng terminal, sa pamamagitan ngstdout stream Sinusubukan ng pangalawang linya na mag-access ng isang file na wala. Lilikha ito ng isang mensahe ng error na naihatid sa pamamagitan ng stderr.

Patakbuhin ang script gamit ang utos na ito:

./error.sh

Maaari naming makita na ang parehong mga stream ng output, stdout at stderr, naipakita sa mga terminal windows.

Subukan nating i-redirect ang output sa isang file:

./error.sh> capture.txt

Ang mensahe ng error na naihatid sa pamamagitan ng stderr ay ipinapadala pa rin sa window ng terminal. Maaari naming suriin ang mga nilalaman ng file upang makita kung ang stdout ang output ay nagpunta sa file.

cat capture.txt

Ang output mula sa si stdin ay nai-redirect sa file tulad ng inaasahan.

Ang > gumagana ang simbolo ng pag-redirect stdout bilang default. Maaari mong gamitin ang isa sa mga taglaraw ng numero ng file upang tukuyin kung aling karaniwang output stream ang nais mong i-redirect.

Upang malinaw na mag-redirect stdout, gamitin ang tagubilin sa pag-redirect:

1>

Upang tahasang mag-redirect stderr, gamitin ang tagubilin sa pag-redirect:

2>

Subukan nating muli ang aming pagsubok, at sa pagkakataong ito gagamitin namin 2>:

./error.sh 2> capture.txt

Ang mensahe ng error ay nai-redirect at ang stdoutecho ang mensahe ay ipinadala sa window ng terminal:

Tingnan natin kung ano ang nasa capture.txt file.

cat capture.txt

Ang stderr ang mensahe ay nasa capture.txt tulad ng inaasahan.

Pag-redirect ng Parehong stdout at stderr

Tiyak, kung maaari din tayong mag-redirect stdout o stderr sa isang file nang nakapag-iisa sa isa't isa, nararapat na ma-redirect namin silang dalawa nang sabay, sa dalawang magkakaibang mga file?

Oo kaya natin. Magdidirekta ang utos na ito stdout sa isang file na tinatawag na capture.txt at stderr sa isang file na tinatawag na error.txt.

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

Dahil ang parehong daloy ng output – karaniwang output at karaniwang error — ay nai-redirect sa mga file, walang nakikitang output sa window ng terminal. Bumabalik kami sa prompt ng linya ng utos na parang walang nangyari.

Suriin natin ang mga nilalaman ng bawat file:

cat capture.txt
error sa pusa.txt

Pag-redirect ng stdout at stderr sa Parehong File

Maayos iyon, nakuha namin ang bawat isa sa mga karaniwang output stream na papunta sa sarili nitong nakalaang file. Ang tanging iba pang kombinasyon na maaari nating gawin ay ang ipadala ang pareho stdout at stderr sa parehong file.

Maaari nating makamit ito sa sumusunod na utos:

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

Basagin natin iyan.

  • ./error.sh: Inilulunsad ang file ng error.sh script.
  • > capture.txt: Pag-redirect ng stdout stream sa capture.txt file. > ay maikli para sa 1>.
  • 2>&1: Gumagamit ito ng &> tagubilin sa pag-redirect. Pinapayagan ka ng tagubiling ito na sabihin sa shell upang makagawa ng isang daloy sa parehong patutunguhan tulad ng isa pang stream. Sa kasong ito, sinasabi namin na "redirect stream 2, stderr, sa parehong patutunguhan na nag-stream ng 1, stdout, ay nai-redirect sa. "

Walang nakikitang output. Nakasisigla iyon.

Suriin natin ang capture.txt file at tingnan kung ano ang nasa loob nito.

cat capture.txt

Parehong ang stdout at stderr na-redirect ang mga stream sa isang file ng patutunguhan.

Upang ma-redirect ang output ng isang stream at tahimik na itinapon, idirekta ang output / dev / null.

Pagtuklas sa Pag-redirect sa loob ng isang Script

Tinalakay namin kung paano maaaring makita ng isang utos kung ang alinman sa mga stream ay nai-redirect, at maaaring pumili na baguhin ang pag-uugali nito nang naaayon. Maaari ba nating magawa ito sa ating sariling mga script? Oo kaya natin. At ito ay isang napakadaling pamamaraan upang maunawaan at gamitin.

I-type ang sumusunod na teksto sa isang editor at i-save ito bilang input.sh.

#! / bin / bash kung [-t 0]; pagkatapos echo stdin na nagmumula sa keyboard iba pa echo stdin na nagmumula sa isang tubo o isang file fi

Gamitin ang sumusunod na utos upang gawin itong maisakatuparan:

chmod + x input.sh

Ang matalino na bahagi ay ang pagsubok sa loob ng mga square bracket. Ang -t Ang opsyong (terminal) ay nagbabalik ng totoo (0) kung ang file na nauugnay sa tagapaglarawan ng file ay magtatapos sa window ng terminal. Ginamit namin ang tagapaglaraw ng file na 0 bilang argumento sa pagsubok, na kumakatawansi stdin.

Kung si stdin ay konektado sa isang window ng terminal ang pagsubok ay magpapatunay na totoo. Kung si stdin ay konektado sa isang file o isang tubo, mabibigo ang pagsubok.

Maaari naming gamitin ang anumang maginhawang text file upang makabuo ng input sa script. Narito gumagamit kami ng isang tinatawag na dummy.txt.

./input.sh <dummy.txt

Ipinapakita ng output na kinikilala ng script na ang pag-input ay hindi nagmumula sa isang keyboard, nagmumula ito sa isang file. Kung pinili mo, mapapalitan mo ang pag-uugali ng iyong script alinsunod dito.

Ito ay sa isang pag-redirect ng file, subukan natin ito sa isang tubo.

pusa dummy.txt | ./input.sh

Kinikilala ng script na ang input nito ay nai-piping dito. O mas tumpak, kinikilala nito minsan pa na ang si stdin ang stream ay hindi konektado sa isang window ng terminal.

Patakbuhin natin ang script na hindi alinman sa mga tubo o pag-redirect.

./input.sh

Ang si stdin Ang stream ay konektado sa window ng terminal, at iniuulat ito ng script nang naaayon.

Upang suriin ang parehong bagay sa output stream, kailangan namin ng isang bagong script. I-type ang sumusunod sa isang editor at i-save ito bilang output.sh.

#! / bin / bash kung [-t 1]; pagkatapos ang echo stdout ay pupunta sa window ng terminal kung hindi man ang echo stdout ay nai-redirect o piped fi

Gamitin ang sumusunod na utos upang gawin itong maisakatuparan:

chmod + x input.sh

Ang tanging makabuluhang pagbabago lamang sa script na ito ay ang pagsubok sa mga square bracket. Gumagamit kami ng digit na 1 upang kumatawan sa deskriptor ng file para sa stdout.

Subukan natin ito. Pipipain namin ang output pusa.

./output | pusa

Kinikilala ng script na ang output nito ay hindi direktang pupunta sa isang window ng terminal.

Maaari din naming subukan ang script sa pamamagitan ng pag-redirect ng output sa isang file.

./output.sh> capture.txt

Walang output sa window ng terminal, tahimik kaming ibinalik sa command prompt. Tulad ng aasahan namin.

Maaari tayong tumingin sa loob ng capture.txt file upang makita kung ano ang nakuha. Gamitin ang sumusunod na utos upang magawa ito.

cat capture.sh

Muli, nakita ng simpleng pagsubok sa aming script na stdout ang stream ay hindi ipinapadala nang direkta sa isang window ng terminal.

Kung patakbuhin namin ang script nang walang anumang mga tubo o pag-redirect, dapat itong makita stdout ay naihatid direkta sa window ng terminal.

./output.sh

At iyon mismo ang nakikita natin.

Mga Daloy Ng Kamalayan

Ang pag-alam kung paano sasabihin kung ang iyong mga script ay konektado sa window ng terminal, o isang tubo, o nai-redirect, pinapayagan kang ayusin ang kanilang pag-uugali nang naaayon.

Ang pag-log at output ng diagnostic ay maaaring mas marami o mas detalyado, depende sa kung pupunta ito sa screen o sa isang file. Ang mga mensahe ng error ay maaaring naka-log sa isang iba't ibang mga file kaysa sa normal na output ng programa.

Tulad ng karaniwang kaso, maraming kaalaman ang nagdadala ng maraming mga pagpipilian.


$config[zx-auto] not found$config[zx-overlay] not found