GNU/Linux >> Tutoriels Linux >  >> Linux

Vous essayez de donner un sens aux syntaxes de redirection Bash et à leurs sorties ?

Je suis nouveau sur Linux et j'essaie de comprendre comment fonctionnent les redirections.

J'ai testé diverses syntaxes pour rediriger stdout et stderr au même fichier, qui ne produisent pas tous les mêmes résultats.

Par exemple, si j'essaie de lister 2 fichiers qui n'existent pas (file1 et file2 ) et 2 qui le font (foo et fz ):

Syntaxe #1 (sans redirection) :

$ ls file1 foo fz file2

Voici la sortie que j'obtiens dans le terminal :

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo  fz

Syntaxe #2 :

Maintenant, avec la redirection :

$ ls file1 foo fz file2 > redirect 2>&1

La redirect le fichier contient la même chose que le résultat pour la syntaxe #1 :

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

Donc, avec les deux syntaxes ci-dessus, il semble que le shell imprime stderr d'abord, puis stdout .

Syntaxe #3 :

Maintenant, si j'essaie avec l'une des syntaxes suivantes :

$ ls file1 foo fz file2 > redirect 2> redirect

ou

$ ls file1 foo fz file2 2> redirect > redirect

Puis la redirect le fichier contiendra ceci :

foo
fz
nnot access file1: No such file or directory
ls: cannot access file2: No such file or directory

Ici, cela ressemble à stdout est imprimé avant stderr , mais ensuite nous voyons que le début de stderr est "tronqué" du même nombre de caractères que stdout .

La stdout est long de 6 caractères (foo fz , retour chariot inclus), donc les 6 premiers caractères du stderr (ls: ca ) ont été écrasés par stdout .
Cela ressemble donc en fait à stderr a été imprimé en premier, et que stdout a ensuite été imprimé sur stderr au lieu d'y être ajouté.

Cependant, cela aurait eu plus de sens pour moi si stderr avait été complètement effacé et remplacé par stdout , plutôt que partiellement écrasé.

Syntaxe #4 :

Le seul moyen que j'ai trouvé pour corriger la syntaxe n ° 3 consiste à ajouter l'opérateur d'ajout au stdout :

$ ls file1 foo fz file2 >> redirect 2> redirect

ou

$ ls file1 foo fz file2 2> redirect >> redirect

Ce qui produit la même chose que la syntaxe #2 :

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

Cet article ici explique que la syntaxe #3 est fausse (vraisemblablement, la syntaxe #4 aussi). Mais pour l'amour de l'argument :pourquoi la syntaxe #3 est-elle fausse ? Que dit-il exactement (ou pas dire) le shell à faire par opposition à la syntaxe #2 ?

Connexe :Quelle est la différence entre $(…) et `…` dans Bash ?

Aussi, y a-t-il une raison pour laquelle la sortie affiche toujours stderr avant stdout ?

Merci !

Réponse acceptée :

C'est comme exécuter deux processus pour écrire dans le même fichier en même temps... mauvaise idée. Vous vous retrouvez avec deux descripteurs de fichiers ouverts différents et vos données peuvent être tronquées (comme c'est le cas au point 3 ci-dessus). L'utilisation de la syntaxe #2 est correcte; ça fait un handle de fichier et pointe à la fois stderr et stdout au même endroit.

Quant au fait que stderr soit toujours imprimé en premier, il n'y a aucune règle à ce sujet. Je soupçonne avec ls c'est parce que ls doit vérifier chaque entrée du répertoire avant de pouvoir déclarer qu'un fichier particulier n'existe pas. Ainsi, plutôt que de faire N passages sur la table de répertoires, il fait un seul passage, vérifiant tous les arguments de ligne de commande donnés, signale les erreurs et imprime les fichiers qu'il a trouvés. D'autres commandes peuvent imprimer sur stderr après stdout, ou même alterner entre elles.


Linux
  1. rechercher et copier un fichier à l'aide de Bash

  2. Extraire le nom de base du fichier sans chemin ni extension dans bash

  3. Essayer d'utiliser bash sous Windows et n'a reçu aucun message de distributions installées

  4. Comment faire en sorte que ls soit trié par extension de fichier puis par nom?

  5. Qu'est-ce que <() dans bash (et =() dans zsh) ?

Bash :Écrire dans un fichier

Commande de source bash

Bash :ajouter au fichier

La redirection bash expliquée avec des exemples

Shell Scripting Part4 - Entrée, sortie et redirection

Obtenir toutes les extensions et leur nombre de fichiers respectifs dans un répertoire