Mi az stdin, stdout és stderr Linux alatt?

stdin, stdoutés stderrhárom adatfolyam jön létre, amikor elindít egy Linux parancsot. Segítségükkel megtudhatja, hogy a parancsfájlok továbbítása vagy átirányítása folyamatban van-e. Megmutatjuk, hogyan.

A patakok két ponthoz csatlakoznak

Amint elkezd tanulni Linux és Unix-szerű operációs rendszerek, akkor találkoznak a feltételeket stdin, stdoutés stederr. Ez három szabványos adatfolyam, amely egy Linux parancs végrehajtásakor jön létre. A számítástechnikában az adatfolyamot továbbíthatja. Ezen adatfolyamok esetében az adat szöveg.

Az adatfolyamoknak, akárcsak a vízfolyásoknak, két végük van. Van forrásuk és kiáramlásuk. Bármelyik Linux-parancsot használja, az egyes folyamok egyik végét biztosítja. A másik végét a parancsot elindító shell határozza meg. Ez a vég csatlakozik a terminál ablakához, egy csőhöz, vagy átirányít egy fájlba vagy más parancsba a parancsot elindító parancssornak megfelelően.

A Linux szabványos adatfolyamok

Linux  stdinalatt a szokásos bemeneti adatfolyam. Ez bevezeti a szöveget. A parancs kimenete a shellbe a stdout(standard out) adatfolyamon keresztül érkezik . A parancs stderrhibaüzeneteit a (standard hiba) adatfolyamon keresztül küldjük .

Tehát láthatjuk, hogy van két kilépő, stdoutés stderr, és egy bemeneti folyam, stdin. Mivel a hibaüzenetek és a normál kimenet mindegyikének megvan a maga csatornája, amely a terminál ablakához viszi őket, egymástól függetlenül kezelhetők.

A folyamokat fájlokként kezeljük

A Linux-adatfolyamokat - mint szinte minden mást - úgy kezeljük, mintha fájlok lennének. Szöveget olvashat egy fájlból, és szöveget írhat fájlba. Mindkét művelet adatfolyamot tartalmaz. Tehát az adatfolyam fájlként történő kezelése nem olyan nagy.

Minden folyamathoz társított fájl egyedi azonosítót kap. Ez fájlleíró néven ismert. Amikor egy műveletet el kell végezni egy fájlon, a fájl azonosítóját a fájlleíróval kell meghatározni.

Ezeket az értékeket mindig használják stdin, stdout,és stderr:

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

Reagálás a csövekre és az átirányításokra

A tantárgy bevezetésének megkönnyítése érdekében általános módszer a téma egyszerűsített változatának tanítása. Például nyelvtannal azt mondják nekünk, hogy a szabály „I előtt E, kivéve C után”. De valójában több kivétel van ez alól a szabály alól, mint ahány esetben ezt betartják.

Hasonló értelemben, amikor beszélünk róla stdin, stdoutés stderr kényelmes ügetni az elfogadott axiómát, miszerint egy folyamat sem nem tudja, sem nem érdekli, hol fejeződik be a három standard folyamata. Kell-e egy folyamatnak törődnie azzal, hogy a kimenete a terminálra megy-e, vagy átirányításra kerül egy fájlba? Meg tudja még tudni, hogy a bemenete a billentyűzetről származik-e, vagy egy másik folyamatból érkezik?

Valójában egy folyamat tud - vagy legalábbis megtudhatja, ha úgy dönt, hogy ellenőrzi -, és ennek megfelelően megváltoztathatja viselkedését, ha a szoftver szerzője úgy dönt, hogy hozzáadja ezt a funkciót.

Nagyon könnyen láthatjuk ezt a viselkedésbeli változást. Próbálja ki ezt a két parancsot:

ls

ls | macska

A lsparancs másképp viselkedik, ha a kimenete ( stdout) egy másik parancsba kerül. Ez az  ls, ami egyetlen oszlop kimenetre vált, és nem ez a konverzió cat. És lsugyanezt teszi, ha a kimenetét átirányítják:

ls> capture.txt

macska elfogása.txt

Az stdout és a stderr átirányítása

Előnye van annak, ha a hibaüzeneteket egy dedikált adatfolyam továbbítja. Ez azt jelenti, hogy át tudjuk irányítani a parancs kimenetét ( stdout) egy fájlba, és továbbra is láthatjuk az esetleges hibaüzeneteket ( stderr) a terminál ablakában. Ha szükséges, reagálhat a hibákra, azok előfordulásakor. Megállítja a hibaüzeneteket az stdoutátirányított fájl szennyezésétől is.

Írja be a következő szöveget egy szerkesztőbe, és mentse el a error.sh nevű fájlba.

#! / bin / bash echo "Nem létező fájlhoz próbálok hozzáférni" cat bad-filename.txt

A parancsfájl futtathatóvá tétele a következő paranccsal:

chmod + x hiba.sh

A szkript első sora a szöveget a terminálablakhoz visszhangozza, a stdoutfolyamon keresztül  . A második sor nem létező fájlhoz próbál hozzáférni. Ez egy hibaüzenetet generál, amelyet a rendszer továbbít stderr.

Futtassa a parancsfájlt ezzel a paranccsal:

./error.sh

Láthatjuk, hogy a kimenet mindkét folyamata stdoutés stderra terminál ablakai megjelennek.

Próbáljuk átirányítani a kimenetet egy fájlba:

./error.sh> capture.txt

A rendszeren keresztül továbbított hibaüzenet stderrtovábbra is a terminál ablakába kerül. Ellenőrizhetjük a fájl tartalmát, hogy a stdout kimenet a fájlhoz került-e.

macska elfogása.txt

A kimenetet a stdinvárakozásnak megfelelően átirányították a fájlba.

Az >átirányítási szimbólum stdoutalapértelmezés szerint működik . A numerikus fájlleírók egyikével jelezheti, hogy melyik szabványos kimeneti adatfolyamot kívánja átirányítani.

A kifejezett átirányításhoz  stdouthasználja ezt az átirányítási utasítást:

1>

A kifejezett átirányításhoz  stderrhasználja ezt az átirányítási utasítást:

2>

Próbáljuk meg újra tesztelni, és ezúttal a következőket fogjuk használni 2>:

./error.sh 2> capture.txt

A hibaüzenet átirányításra kerül, és az stdoutechoüzenet a terminál ablakába kerül:

Lássuk, mi van a capture.txt fájlban.

macska elfogása.txt

Az stderrüzenet a várt módon a capt.txt fájlban található.

Az stdout és a stderr átirányítása

Természetesen, ha bármelyiket stdoutvagy stderrfájlokat egymástól függetlenül tudjuk átirányítani, akkor képesnek kell lenniünk arra, hogy mindkettőt egyszerre, két különböző fájlba irányítsuk?

Igen. Ez a parancs stdouta capture.txt nevű fájlba és stderra error.txt nevű fájlba irányítja.

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

Mivel a kimenet - a standard kimenet és a standard hiba - mindkét adatfolyamát átirányítják a fájlokba, a terminál ablakában nincs látható kimenet. Visszatérünk a parancssorba, mintha mi sem történt volna.

Ellenőrizzük az egyes fájlok tartalmát:

macska elfogása.txt
macska hiba.txt

Az stdout és a stderr átirányítása ugyanarra a fájlra

Ez rendben van, mindegyik szabványos kimeneti adatfolyam a saját dedikált fájljához megy. Az egyetlen másik kombináció, amit tehetünk, hogy küldjön a stdoutés stderrugyanabba a fájlba.

Ezt a következő paranccsal érhetjük el:

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

Ezt bontsuk le.

  • ./error.sh : Elindítja a error.sh parancsfájlt.
  • > capture.txt : Átirányítja az stdoutadatfolyamot a capture.txt fájlba. >gyorsírás 1>.
  • 2> & 1 : Ez a &> átirányítási utasítást használja. Ez az utasítás lehetővé teszi, hogy megmondja a shellnek, hogy az egyik adatfolyam ugyanabba a célba kerüljön, mint egy másik adatfolyam. Ebben az esetben azt mondjuk, hogy „a 2. adatfolyam átirányítása stderrugyanarra a célra, ahová az 1. adatfolyam stdoutátirányításra kerül”.

Nincs látható kimenet. Ez biztató.

Ellenőrizzük a capture.txt fájlt, és nézzük meg, mi van benne.

macska elfogása.txt

A stdoutés az stderradatfolyamokat egyetlen célfájlba irányították át.

Ahhoz, hogy a kimeneti áram átirányított és csendben eldobják, irányítsa a kimenetet /dev/null.

Átirányítás észlelése egy szkripten belül

Megbeszéltük, hogy egy parancs miként képes felismerni, ha valamelyik adatfolyamot átirányítják, és dönthet úgy, hogy ennek megfelelően módosítja a viselkedését. Meg tudjuk valósítani ezt a saját szkriptjeinkkel? Igen. Ez pedig nagyon könnyen megérthető és alkalmazható technika.

Írja be a következő szöveget egy szerkesztőbe, és mentse el input.sh fájlként.

#! / bin / bash if [-t 0]; akkor a billentyűzetről érkező echo stdin egy pipából vagy egy fi fájlból érkező echo stdin

A következő paranccsal futtathatóvá teheti:

chmod + x input.sh

Az okos rész a teszt a szögletes zárójelben. A -t(terminal) opció visszaadja az true (0) értéket, ha a fájlleíróhoz társított fájl véget ér a terminál ablakában. A 0 fájlleírót használtuk a teszt argumentumaként, amely képviseli   stdin.

Ha stdincsatlakozik egy terminálablakhoz, a teszt igaznak bizonyul. Ha stdinfájlhoz vagy csőhöz csatlakozik, a teszt sikertelen lesz.

Bármilyen kényelmes szöveges fájlt használhatunk a szkript bemenetének előállításához. Itt a dummy.txt nevű fájlt használjuk.

./input.sh <dummy.txt

A kimenet azt mutatja, hogy a szkript felismeri, hogy a bemenet nem billentyűzetről származik, hanem fájlról. Ha úgy dönt, ennek megfelelően módosíthatja a szkript viselkedését.

Ez fájl átirányítással történt, próbáljuk meg pipával.

macska dummy.txt | ./input.sh

A szkript felismeri, hogy a bemenete folyamatban van. Vagy pontosabban felismeri még egyszer, hogy az stdinadatfolyam nem kapcsolódik egy terminálablakhoz.

Futtassuk a szkriptet se csövekkel, se átirányításokkal.

./input.sh

Az stdinadatfolyam csatlakozik a terminál ablakához, és a szkript ennek megfelelően jelentést tesz erről.

Ahhoz, hogy ugyanazt ellenőrizzük a kimeneti folyammal, szükségünk van egy új parancsfájlra. Írja be a következőket egy szerkesztőbe, és mentse el output.sh fájlként.

#! / bin / bash if [-t 1]; akkor az echo stdout a terminál ablakába kerül, másképp az echo stdout átirányításra vagy csövezésre kerül

A következő paranccsal futtathatóvá teheti:

chmod + x input.sh

Az egyetlen jelentős változás ebben a szkriptben a szögletes zárójelben lévő tesztben történik. Az 1. számjegyet használjuk a fájlleíró ábrázolására stdout.

Próbáljuk ki. Átvezetjük a kimenetet cat.

./output | macska

A szkript felismeri, hogy a kimenete nem közvetlenül a terminál ablakába kerül.

A szkriptet tesztelhetjük úgy is, hogy a kimenetet egy fájlba irányítjuk.

./output.sh> capture.txt

Nincs kimenet a terminál ablakába, csendben visszatérünk a parancssorba. Ahogy számítottunk rá.

Belenézhetünk a capture.txt fájlba, hogy megnézzük, mit rögzítettünk. Ehhez használja a következő parancsot.

macskafogás.sh

A szkriptünk egyszerű tesztje ismét azt észleli, hogy a stdoutfolyamot nem közvetlenül a terminálablakba küldik.

Ha a parancsfájlt csövek és átirányítás nélkül futtatjuk, akkor észlelnie kell, stdouthogy közvetlenül a terminál ablakába kerül.

./output.sh

És pontosan ezt látjuk.

Tudatfolyamok

Annak ismerete, hogy megtudja, hogy a szkriptjei csatlakoznak-e a terminál ablakához, vagy egy csőhöz, vagy átirányításra kerülnek, lehetővé teszi a viselkedésük ennek megfelelő beállítását.

A naplózás és a diagnosztikai kimenet többé-kevésbé részletes lehet, attól függően, hogy a képernyőre vagy egy fájlra kerül-e. A hibaüzeneteket a normál program kimenetétől eltérő fájlba lehet naplózni.

Mint általában, a több tudás több lehetőséget kínál.