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 stderr
et 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 de1>
. - 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);