Què són stdin, stdout i stderr a Linux?
stdin
, stdout
, i stderr
són tres fluxos de dades creats quan s'inicia una ordre de Linux. Podeu utilitzar-los per saber si els vostres scripts s’estan canalitzant o redirigint. Us mostrem com fer-ho.
Els corrents s’uneixen a dos punts
Tan bon punt comenceu a obtenir informació sobre sistemes operatius similars a Linux i Unix, trobareu els termes stdin
, stdout
, i stederr
. Es tracta de tres fluxos estàndard que s’estableixen quan s’executa una ordre de Linux. En informàtica, un flux és una cosa que pot transferir dades. En el cas d’aquests fluxos, aquestes dades són text.
Els fluxos de dades, com els fluxos d’aigua, tenen dos extrems. Tenen una font i una sortida. Qualsevol ordre de Linux que utilitzeu proporciona un extrem de cada flux. L'altre extrem està determinat per l'intèrpret d'ordres que va iniciar l'ordre. Aquest extrem es connectarà a la finestra del terminal, es connectarà a una canonada o es redirigirà a un fitxer o a una altra ordre, segons la línia d'ordres que va iniciar l'ordre.
Els corrents estàndard de Linux
A Linux,stdin
és el flux d'entrada estàndard. Això accepta el text com a entrada. La sortida de text de l'ordre a l'intèrpret d'ordres es lliura mitjançant el fitxer stdout
(sortida estàndard). Els missatges d'error de l'ordre s'envien a través de stderr
corrent (error estàndard).
Per tant, podeu veure que hi ha dos fluxos de sortida, stdout
i stderr
, i un flux d'entrada, stdin
. Com que els missatges d'error i la sortida normal tenen cadascun el seu propi conducte per portar-los a la finestra del terminal, es poden gestionar independentment els uns dels altres.
Els fluxos es gestionen com fitxers
Els fluxos a Linux, com gairebé tota la resta, es tracten com si fossin fitxers. Podeu llegir text d’un fitxer i escriure text en un fitxer. Ambdues accions impliquen un flux de dades. Per tant, el concepte de gestionar un flux de dades com a fitxer no és tan extens.
A cada fitxer associat a un procés se li assigna un número únic per identificar-lo. Això es coneix com el descriptor de fitxers. Sempre que cal dur a terme una acció sobre un fitxer, el descriptor de fitxers s’utilitza per identificar-lo.
Aquests valors sempre s’utilitzen per stdin
, stdout,
i stderr
:
- 0: stdin
- 1: stdout
- 2: stderr
Reacció a canonades i redireccions
Per facilitar la introducció d’una assignatura a algú, una tècnica habitual és ensenyar una versió simplificada del tema. Per exemple, amb la gramàtica, se'ns diu que la regla és "Jo abans que E, excepte després de C." Però, en realitat, hi ha més excepcions a aquesta regla que no hi ha casos que l’obeeixin.
En un sentit similar, quan es parla de stdin
, stdout
, i stderr
és convenient esbrinar l'axioma acceptat que un procés no coneix ni es preocupa per on acaben els seus tres corrents estàndard. A un procés li importa si la seva sortida va al terminal o es redirigeix a un fitxer? Fins i tot es pot saber si la seva entrada prové del teclat o s’introdueix en un altre procés?
De fet, un procés ho sap (o almenys ho pot saber, si vol optar per comprovar-ho) i pot canviar el seu comportament en conseqüència si l'autor del programari va decidir afegir aquesta funcionalitat.
Podem veure aquest canvi de comportament molt fàcilment. Proveu aquestes dues ordres:
ls
ls | gat
El ls
l'ordre es comporta de manera diferent si la seva sortida (stdout
) s'està enviant a una altra ordre. Ésls
que canvia a una única columna de sortida, no és una conversió realitzada per gat
. I ls
fa el mateix si es redirigeix la seva sortida:
ls> capture.txt
cat capture.txt
Redirecció de stdout i stderr
Hi ha un avantatge a l’hora de rebre missatges d’error mitjançant un flux dedicat. Vol dir que podem redirigir la sortida d’una ordre (stdout
) a un fitxer i encara veieu els missatges d'error (stderr
) a la finestra del terminal. Podeu reaccionar als errors si cal, tal com es produeixen. També impedeix que els missatges d'error contaminin el fitxer que stdout
s'ha redirigit a.
Escriviu el text següent en un editor i deseu-lo en un fitxer anomenat error.sh.
#! / bin / bash echo "A punt d'intentar accedir a un fitxer que no existeix" cat bad-filename.txt
Feu que l'script sigui executable amb aquesta ordre:
chmod + x error.sh
La primera línia de l'script fa ressò del text a la finestra del terminal, mitjançant el fitxerstdout
corrent. La segona línia intenta accedir a un fitxer que no existeix. Això generarà un missatge d'error que s'envia mitjançant stderr
.
Executeu l'script amb aquesta ordre:
./error.sh
Podem veure que tots dos fluxos de sortida, stdout
i stderr
, s'han mostrat a les finestres del terminal.
Intentem redirigir la sortida a un fitxer:
./error.sh> capture.txt
El missatge d'error que s'envia mitjançant stderr
encara s’envia a la finestra del terminal. Podem comprovar el contingut del fitxer per veure si el fitxer stdout
la sortida va anar al fitxer.
cat capture.txt
La sortida de stdin
s'ha redirigit al fitxer tal com s'esperava.
El >
el símbol de redirecció funciona amb stdout
per defecte. Podeu utilitzar un dels descriptors de fitxers numèrics per indicar el flux de sortida estàndard que voleu redirigir.
Per redirigir explícitament stdout
, utilitzeu aquesta instrucció de redirecció:
1>
Per redirigir explícitament stderr
, utilitzeu aquesta instrucció de redirecció:
2>
Tornem a provar la nostra prova i aquesta vegada la farem servir 2>
:
./error.sh 2> capture.txt
El missatge d'error es redirigeix i el fitxer stdout
ressò
s'envia un missatge a la finestra del terminal:
Vegem què hi ha al fitxer capture.txt.
cat capture.txt
El stderr
el missatge es troba a capture.txt com s’esperava.
Redirecció de stdout i stderr
Segurament, si podem redirigir qualsevol dels dos stdout
o bé stderr
a un fitxer independentment els uns dels altres, hauríem de ser capaços de redirigir-los tots dos alhora, a dos fitxers diferents?
Si podem. Aquesta ordre es dirigirà stdout
a un fitxer anomenat capture.txt i stderr
a un fitxer anomenat error.txt.
./error.sh 1> capture.txt 2> error.txt
Com que els dos fluxos de sortida (sortida estàndard i error estàndard) es redirigeixen a fitxers, no hi ha cap sortida visible a la finestra del terminal. Tornem a la sol·licitud de línia d'ordres com si res no hagués passat.
Comprovem el contingut de cada fitxer:
cat capture.txt
cat error.txt
Redirigint stdout i stderr al mateix fitxer
Això és bo, tenim cadascun dels fluxos de sortida estàndard al seu propi fitxer dedicat. L’única altra combinació que podem fer és enviar les dues coses stdout
i stderr
al mateix fitxer.
Ho podem aconseguir amb l'ordre següent:
./error.sh> capture.txt 2> & 1
Desglossem això.
- ./error.sh: Inicia el fitxer de script error.sh.
- > capture.txt: Redirigeix el fitxer
stdout
transmetre al fitxer capture.txt.>
és abreviatura de1>
. - 2>&1: Utilitza la instrucció de redirecció &>. Aquesta instrucció us permet indicar a l'intèrpret d'ordres que un flux arribi al mateix destí que un altre. En aquest cas, diem "redirigeix el flux 2,
stderr
, al mateix destí que el flux 1,stdout
, s'està redirigint a ".
No hi ha cap sortida visible. Això és encoratjador.
Comprovem el fitxer capture.txt i comprovem què hi ha.
cat capture.txt
Tant el stdout
i stderr
els fluxos s'han redirigit a un únic fitxer de destinació.
Per fer que la sortida d’un flux es redirigeixi i es llenci en silenci, dirigeixi la sortida cap a / dev / null
.
Detecció de redirecció dins d'un script
Vam discutir com una ordre pot detectar si es redirigeix algun dels fluxos i pot optar per modificar-ne el comportament en conseqüència. Ho podem aconseguir amb els nostres propis scripts? Si podem. I és una tècnica molt fàcil d’entendre i emprar.
Escriviu el text següent en un editor i deseu-lo com a input.sh.
#! / bin / bash si [-t 0]; llavors ressona stdin que prové del teclat; si no, ressona stdin provinent d’un tub o d’un fitxer fi
Utilitzeu l'ordre següent per fer-lo executable:
chmod + x input.sh
La part intel·ligent és la prova entre claudàtors. El -t
L'opció (terminal) retorna true (0) si el fitxer associat amb el descriptor del fitxer finalitza a la finestra del terminal. Hem utilitzat el descriptor de fitxer 0 com a argument de la prova, que representastdin
.
Si stdin
està connectat a una finestra del terminal, la prova serà certa. Si stdin
està connectat a un fitxer o una canonada, la prova fallarà.
Podem utilitzar qualsevol fitxer de text convenient per generar entrades a l'script. Aquí en fem servir un anomenat dummy.txt.
./input.sh <dummy.txt
La sortida mostra que l'script reconeix que l'entrada no prové d'un teclat, sinó d'un fitxer. Si ho decidiu, podríeu variar el comportament del vostre script en conseqüència.
Va ser amb una redirecció de fitxers, provem-ho amb una canonada.
cat dummy.txt | ./input.sh
El guió reconeix que s’està enviant la seva entrada. O, més exactament, reconeix una vegada més que el stdin
stream no està connectat a una finestra de terminal.
Executem l'script sense canalitzacions ni redireccions.
./input.sh
El stdin
stream està connectat a la finestra del terminal i l'script informa d'això en conseqüència.
Per comprovar el mateix amb el flux de sortida, necessitem un nou script. Escriviu el següent en un editor i deseu-lo com a output.sh.
#! / bin / bash if [-t 1]; llavors echo stdout es dirigeix a la finestra del terminal; en cas contrari, echo stdout es redirigeix o canalitza fi
Utilitzeu l'ordre següent per fer-lo executable:
chmod + x input.sh
L’únic canvi significatiu d’aquest script es troba a la prova entre claudàtors. Estem fent servir el dígit 1 per representar el descriptor del fitxer stdout
.
Provem-ho. Canviarem la sortida gat
.
./output | gat
El script reconeix que la seva sortida no va directament a una finestra de terminal.
També podem provar l'script redirigint la sortida a un fitxer.
./output.sh> capture.txt
No hi ha cap sortida a la finestra del terminal, tornem silenciosament a l'indicador d'ordres. Com esperaríem.
Podem mirar dins del fitxer capture.txt per veure què es va capturar. Utilitzeu l'ordre següent per fer-ho.
captura de gat.sh
De nou, la prova senzilla del nostre script detecta que el fitxer stdout
el flux no s’envia directament a una finestra de terminal.
Si executem l'script sense cap canalització ni redirecció, hauria de detectar-ho stdout
s’envia directament a la finestra del terminal.
./output.sh
I això és exactament el que veiem.
Corrents de consciència
Saber saber si els vostres scripts estan connectats a la finestra del terminal, a una canonada o si s’estan redirigint, us permet ajustar el seu comportament en conseqüència.
El registre i la sortida de diagnòstic poden ser més o menys detallats, depenent de si es dirigeix a la pantalla o a un fitxer. Els missatges d'error es poden registrar en un fitxer diferent de la sortida normal del programa.
Com sol passar, més coneixements aporten més opcions.