GNU/Linux >> Tutoriels Linux >  >> Linux

Comment rediriger la sortie de la commande shell

Les scripts shell offrent une fonctionnalité très puissante :la possibilité de rediriger la sortie des commandes et des scripts et de l'envoyer vers des fichiers, des périphériques ou même comme entrée d'autres commandes ou scripts.

Cet article se concentre sur la sortie des commandes et des scripts.

Types de sortie

Les commandes et les scripts d'un shell peuvent générer deux types de sortie de base :

  • SORTIE STD : La sortie normale d'une commande/script (descripteur de fichier 1)
  • STDERR : La sortie d'erreur d'une commande/script (descripteur de fichier 2)

Par défaut, STDOUT et STDERR sont envoyés sur l'écran de votre terminal.

En termes d'entrée, STDIN lit par défaut les entrées du clavier (descripteur de fichier 0). Un descripteur de fichier est un identifiant unique pour un fichier ou une autre ressource d'E/S.

Comment rediriger la sortie du shell

Il existe plusieurs façons de rediriger la sortie des scripts et commandes shell.

1. Rediriger STDOUT

Pour les exemples suivants, j'utiliserai ce simple ensemble de fichiers :

$ls -la file*
-rw-r--r--. 1 admin2 admin2  7 Mar 27 15:34 file1.txt
-rw-r--r--. 1 admin2 admin2 10 Mar 27 15:34 file2.txt
-rw-r--r--. 1 admin2 admin2 13 Mar 27 15:34 file3.txt

J'exécute un simple ls commandes pour illustrer STDOUT vs STDERR, mais le même principe s'applique à la plupart des commandes que vous exécutez à partir d'un shell.

Je peux rediriger la sortie standard vers un fichier en utilisant ls file* > my_stdout.txt :

$ls file* > my_stdout.txt

$ cat my_stdout.txt 
file1.txt
file2.txt
file3.txt

Ensuite, je lance une commande similaire, mais avec un 1 avant > . Redirection à l'aide du > signal est identique à l'utilisation de 1> pour ce faire:je dis au shell de rediriger le STDOUT vers ce fichier. Si j'omets le descripteur de fichier, STDOUT est utilisé par défaut. Je peux le prouver en exécutant le sdiff commande pour afficher la sortie des deux commandes côte à côte :

$ls file* 1> my_other_stdout.txt

$sdiff my_stdout.txt my_other_stdout.txt
file1.txt			             file1.txt
file2.txt			             file2.txt
file3.txt			             file3.txt

Comme vous pouvez le voir, les deux sorties ont le même contenu.

2. Rediriger STDERR

Maintenant, quelle est la particularité de STDERR ? Pour démontrer, je vais introduire une condition d'erreur dans l'exemple précédent avec ls file* non-existing-file* > my_normal_output.txt :

Voici le résultat :

Image

Voici quelques observations du test ci-dessus :

  1. La sortie concernant les fichiers existants est correctement envoyée au fichier de destination.
  2. L'erreur (qui s'affiche lorsque j'essaie de lister quelque chose qui n'existe pas) est envoyée à l'écran. Il s'agit de l'endroit par défaut où les erreurs sont envoyées, sauf si vous les redirigez.

[ Téléchargez une feuille de triche pour les scripts Bash Shell. ]

Ensuite, je vais rediriger la sortie d'erreur en référençant explicitement le descripteur de fichier 2 avec  ls file* non-existing-file* > my_normal_output.txt 2> my_error_output.txt:

Image

Dans l'exemple ci-dessus :

  1. Le ls la commande n'affiche pas le message d'erreur à l'écran comme avant.
  2. La sortie normale contient ce que j'attends.
  3. Le message d'erreur est envoyé au my_error_output.txt fichier.

3. Envoyer STDOUT et STDERR au même fichier

Une autre situation courante consiste à envoyer à la fois STDOUT et STDERR au même fichier :

$ls file* non-existing-file* > my_consolidated_output.txt 2>&1

$ cat my_consolidated_output.txt 
ls: cannot access 'non-existing-file*': No such file or directory
file1.txt
file2.txt
file3.txt

Dans cet exemple, toutes les sorties (normales et d'erreur) sont envoyées dans le même fichier.

Le 2>&1 construction signifie "envoyer le STDERR au même endroit que vous envoyez le STDOUT ."

4. Rediriger la sortie, mais ajouter le fichier

Dans tous les exemples précédents, chaque fois que je redirigeais une sortie, j'utilisais un seul > , ce qui signifie "envoyer quelque chose à ce fichier et démarrer le fichier à partir de zéro ." Par conséquent, si le fichier de destination existe, il est écrasé.

Si je veux ajouter à un fichier existant, j'ai besoin d'utiliser >> . Si le fichier n'existe pas déjà, il sera créé :

$echo "Adding stuff to the end of a file" >> my_output.txt

$cat my_output.txt 
file1.txt
file2.txt
file3.txt
Adding stuff to the end of a file

5. Rediriger vers un autre processus ou vers nulle part

Les exemples ci-dessus couvrent la redirection de la sortie vers un fichier, mais vous pouvez également rediriger les sorties vers d'autres processus ou dev/null .

L'envoi de la sortie à d'autres processus est l'une des fonctionnalités les plus puissantes d'un shell. Pour cette tâche, utilisez le | (tuyau), qui envoie la sortie d'une commande à l'entrée de la commande suivante :

ps -ef | grep chrome | grep -v grep | wc -l
21

L'exemple ci-dessus répertorie mes processus, filtre ceux qui contiennent la chaîne chrome , ignore la ligne concernant mon grep commande et compte les lignes résultantes. Si je veux envoyer la sortie dans un fichier, j'ajoute > et un nom de fichier à la fin de la chaîne.

Enfin, voici un exemple où je souhaite ignorer l'une des sorties, le STDERR :

$tar cvf my_files.tar file* more-non-existing*
file1.txt
file2.txt
file3.txt
tar: more-non-existing*: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

Parce que le tar la commande n'a trouvé aucun fichier dont le nom commence par more-non-existing , certains messages d'erreur s'affichent à la fin.

Supposons que je crée des scripts et que je ne me soucie pas de voir ou de capturer ces erreurs (je sais, dans la vraie vie, vous devriez prévenir et gérer les erreurs, pas simplement les ignorer) :

$tar cvf my_files.tar file* more-non-existing* 2> /dev/null
file1.txt
file2.txt
file3.txt

Le /dev/null est un fichier de périphérique spécial qui ressemble à un "trou noir" :ce que vous y envoyez disparaît tout simplement.

[ Téléchargez ce guide d'installation d'applications sous Linux. ]

6. Utiliser la redirection dans un script

Image
=== SUMMARY OF INVESTIGATION OF chrome ===
Date/Time of the execution: 2022-03-25 18:05:50
Number of processes found.: 5
PIDs:
1245475
1249558
1316941
1382460
1384452

Ce script très simple fait ce qui suit :

  • Ligne 3 :exécute une commande dans le système d'exploitation et l'enregistre dans la variable DATE_TIME.
  • Ligne 6 :exécute le ps commande et redirige vers grep et à un fichier.
    • Au lieu d'envoyer la sortie vers un fichier, je pourrais l'envoyer vers une variable (comme à la ligne 3), mais dans ce cas, je veux exécuter d'autres actions en utilisant la même sortie, donc je la capture. Dans une situation plus réaliste, avoir le fichier pourrait également être utile pendant le développement ou le dépannage, afin que je puisse plus facilement enquêter sur ce que la commande génère.
  • Ligne 8 :exécute des commandes supplémentaires, redirige les sorties vers wc , et affecte le résultat à une variable.
  • Ligne 9 :Utilise awk pour sélectionner uniquement la colonne 2 dans la sortie et la trier par ordre décroissant (juste pour ajouter un autre tube).

Récapitulez

Ce sont quelques exemples de redirection de STDOUT et STDERR. En mettant tout cela ensemble, vous réalisez à quel point la redirection peut être puissante. En enchaînant des commandes individuelles, en manipulant leur sortie et en utilisant le résultat comme entrée pour la commande suivante, vous pouvez effectuer des tâches qui, autrement, pourraient vous obliger à développer un script ou un programme. Vous pouvez également incorporer la technique dans d'autres scripts, en utilisant tout comme blocs de construction.


Linux
  1. Comment affecter la sortie d'une commande à une variable Shell ?

  2. Comment rediriger la sortie d'un programme vers un fichier Zip ? ?

  3. Comment rediriger la sortie vers un fichier et stdout

  4. Comment rediriger la sortie d'un processus déjà en cours d'exécution

  5. Comment ajouter la sortie à un fichier ?

Comment enregistrer la sortie de la commande Linux dans une image ou un fichier texte

Comment rediriger la sortie de la commande time vers un fichier sous Linux ?

Comment rediriger toute la sortie de spark-submit vers un fichier

Comment rediriger la sortie du programme comme son entrée

Comment imprimer la sortie de la commande Linux dans un fichier ?

Comment rediriger la sortie d'une commande vers un fichier lorsque la commande demandera des entrées utilisateur ?