Qu'est-ce que stdin, stdout et stderr sous Linux?

Contenu

Fenêtre de terminal sur un ordinateur Linux

stdin, stdout, et stderr il y a trois flux de données qui sont créés lors du démarrage d'une commande Linux. Vous pouvez les utiliser pour savoir si vos scripts sont redirigés ou redirigés. Nous vous montrons comment.

Les ruisseaux rejoignent deux points

Dès que vous commencez à vous familiariser avec les systèmes d'exploitation Linux et Unix, tu trouveras les termes stdin, stdout, et stederr. Ceux-ci sont trois flux standards qui sont définis lors de l'exécution d'une commande Linux. En informatique, un flux est quelque chose qui peut transférer des données. Dans le cas de ces flux, ces données sont du texte.

Flux de données, comme des ruisseaux d'eau, avoir deux extrémités. Ils ont une source et un exutoire. Quelle que soit la commande Linux que vous utilisez, fournit une extrémité de chaque séquence. L'autre extrême est déterminé par le shell qui a lancé la commande. Cette extrémité se connectera à la fenêtre du terminal, se connectera à un tuyau ou redirigera vers un fichier ou une autre commande, selon la ligne de commande qui a lancé la commande.

Flux standard Linux

En Linux, stdin est le flux d'entrée standard. Ceci accepte le texte en entrée. La sortie texte de la commande au shell est envoyée via le stdout (sortie standard) courant. Les messages d'erreur de commande sont envoyés via le stderr (erreur standard) couler.

Vous pouvez donc voir qu'il y a deux flux de sortie, stdout et stderret un afflux, stdin. Parce que les messages d'erreur et la sortie normale ont chacun leur propre conduit pour conduire à la fenêtre du terminal, peuvent fonctionner indépendamment les uns des autres.

Les flux sont traités comme des fichiers

Flux sous Linux, comme presque tout le reste, sont traités comme s'il s'agissait de fichiers. Vous pouvez lire du texte à partir d'un fichier et vous pouvez écrire du texte dans un fichier. Les deux actions impliquent un flux de données. Ensuite, le concept de gestion d'un flux de données comme un fichier n'est pas si exagéré.

Chaque fichier associé à une procédure se voit attribuer un numéro unique pour l'identifier. C'est ce qu'on appelle un descripteur de fichier.. Chaque fois qu'une action est requise sur un fichier, le descripteur de fichier est utilisé pour identifier le fichier.

Ces valeurs sont toujours utilisées pour stdin, stdout, et stderr:

  • 0: standard
  • 1: sortie standard
  • 2: stderr

Réaction aux tuyaux et aux redirections

Pour faciliter l'introduction de quelqu'un à un sujet, une technique courante consiste à enseigner une version simplifiée du sujet. Par exemple, avec la grammaire, on nous dit que la règle est “I avant E, sauf après C.” Mais en réalité, il y a il y a plus d'exceptions à cette règle qu'il y a des cas qui lui obéissent.

Dans une ligne similaire, Quand tu parles de stdin, stdout, et stderr Il est commode d'exposer l'axiome accepté selon lequel une procédure ne sait ni ne se soucie de la fin de ses trois flux standard.. Si une procédure se soucie si sa sortie va au terminal ou si elle est redirigée vers un fichier? Pouvez-vous même dire si votre entrée provient du clavier ou est acheminée vers celui-ci à partir d'une autre procédure?

En réalité, une procédure sait, ou au moins tu peux découvrir, si vous décidez de le vérifier, et vous pouvez modifier votre comportement en conséquence si l'auteur du logiciel décide d'ajouter cette fonctionnalité.

On voit très facilement ce changement de comportement. Essayez ces deux commandes:

ls

ls | chat

Les ls La commande se comporte différemment si sa sortie (stdout) est redirigé vers une autre commande. Est ls qui se transforme en une sortie de colonne unique, ce n'est pas une conversion effectuée par cat. Oui ls fait de même si votre sortie est redirigée:

ls > capture.txt

capture de chat.txt

Redirigir stdout et stderr

il y a un avantage à ce que les messages d’erreur soient envoyés via une transmission dédiée. Cela signifie que nous pouvons rediriger la sortie d’une commande (stdout) à un fichier et continuer à voir les messages d’erreur (stderr) dans la fenêtre du terminal. Peut réagir aux erreurs si nécessaire, au fur et à mesure qu’ils se produisent. En même temps, il empêche les messages d’erreur de contaminer le fichier qui stdout a été redirigé vers.

Tapez le texte suivant dans un éditeur et enregistrez-le dans un fichier appelé error.sh.

#!/bin/bash

echo "Sur le point d'essayer d'accéder à un fichier qui n'existe pas"
cat nom_de_fichier_mauvais.txt

Rendre le script exécutable avec cette commande:

chmod +x erreur.sh

La première ligne du script fait écho au texte dans la fenêtre du terminal, par stdout Arroyo. La deuxième ligne essaie d'accéder à un fichier qui n'existe pas. Cela générera un message d'erreur qui sera envoyé via stderr.

Exécutez le script avec cette commande:

./erreur.sh

Nous pouvons voir que les deux flux de sortie, stdout et stderr, ont été affichés dans les fenêtres du terminal.

Essayons de rediriger la sortie vers un fichier:

./erreur.sh > capture.txt

Le message d'erreur qui est envoyé par stderr toujours envoyer à la fenêtre du terminal. Nous pouvons vérifier le contenu du fichier pour voir si le stdout la sortie est allée au fichier.

capture de chat.txt

La sortie de stdin a été redirigé vers le fichier comme prévu.

Les > le symbole de redirection fonctionne avec stdout par défaut. Vous pouvez utiliser l'un des descripteurs de fichiers numériques pour indiquer le flux de sortie standard que vous souhaitez rediriger.

Pour rediriger explicitement stdout, utiliser cette instruction de redirection:

1>

Pour rediriger explicitement stderr, utiliser cette instruction de redirection:

2>

Essayons à nouveau notre test, et cette fois nous utiliserons 2>:

./erreur.sh 2> capture.txt

Le message d'erreur est redirigé et le stdout echo Le message est envoyé à la fenêtre du terminal:

Voyons ce qu'il y a dans le fichier capture.txt.

capture de chat.txt

Les stderr le message est dans capture.txt comme prévu.

Rediriger à la fois stdout et stderr

Certainement, si on peut rediriger stdout O stderr dans un fichier indépendamment les uns des autres, Doit-on pouvoir rediriger les deux en même temps, à deux fichiers différents?

Si nous pouvons. Cette commande dirigera stdout dans un fichier appelé capture.txt et stderr dans un fichier appelé error.txt.

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

Parce que les deux sorties, sortie standard et erreur standard, rediriger vers des fichiers, pas de sortie visible dans la fenêtre du terminal. On revient à la ligne de commande comme si de rien n'était.

Passons en revue le contenu de chaque fichier:

capture de chat.txt
erreur de chat.txt

Rediriger stdout et stderr vers le même fichier

Ça c'est génial, nous avons chacun des flux de sortie standard allant vers son propre fichier dédié. La seule autre combinaison que nous pouvons faire est d'envoyer les deux stdout et stderr au même fichier.

Nous pouvons y parvenir avec la commande suivante:

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

Analysons ça.

  • ./erreur.sh: Démarrez le fichier de script error.sh.
  • > capture.txt: Rediriger le stdout flux vers le fichier capture.txt. > est l'abréviation de 1>.
  • 2> et 1: Utiliser l'instruction de redirection &>. Cette instruction vous permet de dire au shell de faire en sorte qu'un flux atteigne la même destination qu'un autre flux. Dans cette circonstance, nous disons “flux de redirection 2, stderr, vers la même destination que le flux 1, stdout, est redirigé vers “.

Pas de sortie visible. c'est encourageant.

Examinons le fichier capture.txt et voyons ce qu'il contient.

capture de chat.txt

Les deux stdout et stderr les flux ont été redirigés vers un seul fichier de destination.

Pour que la sortie d’une séquence soit redirigée et ignorée silencieusement, diriger la sortie vers /dev/null.

Détection de redirection dans un script

Nous discutons de la façon dont une commande peut détecter si l’une des transmissions est redirigée et peut choisir de modifier son comportement en conséquence.. Pouvons-nous y parvenir dans nos propres scripts ?? Si nous pouvons. Et c’est une technique très facile à comprendre et à utiliser.

Tapez le texte suivant dans un éditeur et enregistrez-le sous input.sh.

#!/bin/bash

if [ -t 0 ]; then

  echo stdin coming from keyboard
 
else

  echo stdin coming from a pipe or a file
 
fi

utilisez la commande suivante pour le rendre exécutable:

chmod +x input.sh

La partie intelligente est le test entre crochets. Les -t L'option (Terminal) renvoie true (0) si le fichier associé au descripteur de fichier se termine dans la fenêtre du terminal. Nous avons utilisé le descripteur de fichier 0 comme argument pour le test, qui représente stdin.

Et stdin est connecté à une fenêtre de terminal, la preuve sera vraie. Et stdin est connecté à un fichier ou à un pipeline, le test échouera.

Nous pouvons utiliser n'importe quel fichier texte pratique pour générer des entrées pour le script. Ici, nous en utilisons un appelé dummy.txt.

./entrée.sh < factice.txt

La sortie montre que le script reconnaît que l'entrée ne provient pas d'un clavier, mais à partir d'un fichier. Si vous le souhaitez, vous pouvez modifier le comportement de votre script en conséquence.

C'était avec une redirection de fichier, essayons avec un tuyau.

mannequin de chat.txt | ./entrée.sh

Le script reconnaît que son entrée est redirigée. Ou plus exactement, reconnaît une fois de plus que le stdin le flux n’est pas connecté à une fenêtre de terminal.

Exécutons le script sans pipelines ni redirections.

./entrée.sh

Les stdin le flux est connecté à la fenêtre du terminal, et le script le signale en conséquence.

Pour vérifier la même chose avec le débit sortant, nous avons besoin d’un nouveau script. Tapez ce qui suit dans un éditeur et enregistrez-le sous output.sh.

#!/bin/bash

if [ -t 1 ]; then

echo stdout is going to the terminal window
 
else

echo stdout is being redirected or piped
 
fi

utilisez la commande suivante pour le rendre exécutable:

chmod +x input.sh

Le seul changement significatif dans ce script est dans le test entre crochets. Nous utilisons le chiffre 1 pour rendre le descripteur de fichier pour stdout.

Probemoslo. Nous allons conduire la sortie à travers cat.

./sortir | chat

Le script reconnaît que sa sortie ne va pas directement à une fenêtre de terminal.

En même temps, nous pouvons tester le script en redirigeant la sortie vers un fichier.

./sortie.sh > capture.txt

Pas de sortie dans la fenêtre du terminal, nous sommes renvoyés silencieusement à l'invite de commande. Comment pourrions-nous attendre.

Nous pouvons regarder à l'intérieur du fichier capture.txt pour voir ce qui a été capturé. Utilisez la commande suivante pour le faire.

capture de chat.sh

De nouveau, le test simple dans notre script détecte que le stdout le flux n'est pas envoyé directement à une fenêtre de terminal.

Si nous exécutons le script sans pipelines ni redirections, devrait détecter que stdout est envoyé directement à la fenêtre du terminal.

./sortie.sh

Et c'est exactement ce que nous voyons.

Courants de conscience

Sachez savoir si vos scripts sont connectés à la fenêtre du terminal, ou un tuyau, ou s'ils sont redirigés, vous permet d'ajuster votre comportement en conséquence.

Le journal et la sortie de diagnostic peuvent être plus ou moins détaillés, selon que l'on passe à l'écran ou à un fichier. Les messages d'erreur peuvent être enregistrés dans un fichier autre que la sortie normale du programme.

Comme c'est généralement le cas, plus de connaissances apporte plus d'options.

setTimeout(fonction(){
!fonction(F,b,e,v,m,t,s)
{si(f.fbq)revenir;n=f.fbq=fonction(){n.callMethod?
n.callMethod.apply(m,arguments):n.queue.push(arguments)};
si(!f._fbq)f._fbq=n;n.push=n;n.chargé=!0;n.version=’2.0′;
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertAvant(t,s) } (window, document,'scénario',
'https://connect.facebook.net/en_US/fbevents.js’);
fbq('init', « 335401813750447 »);
fbq('Piste', « Page View »);
},3000);

Abonnez-vous à notre newsletter

Nous ne vous enverrons pas de courrier SPAM. Nous le détestons autant que vous.