{nowwecode.com}

Récupérer uniquement stdout ou stderr sous Bash

Récupérer uniquement stdout ou stderr sous Bash
Illustration de Markus Spiske

Comme exemple je vais utiliser la commande ls.
J'ai dans mon dossier un seul fichier hello.txt, si je lance la commande suivante :

ls hello.txt goodbye.txt

L'interpréteur va nous dire:

  • Sur la sortie d'erreur standard (stderr) que le fichier goodbye.txt n'existe pas.
  • Sur la sortie standard (stdout) qu'il a trouvé le fichier hello.txt.
nowwecode:~$ ls hello.txt goodbye.txt
ls: cannot access 'goodbye.txt': No such file or directory
hello.txt

Comment ne récupérer que l'erreur, ou que la sortie standard ? C'est une question de flux.

Une question de flux

Chaque processus sous Linux produit trois flux de données:

  • stdin
  • stdout
  • stderr

Chaque flux est associé à un identifiant numérique qui nous permet des opérations dessus:

Pointeur Flux Identifiant numérique
stdin Entrée standard 0
stdout Sortie standard 1
stderr Erreur standard 2

Code retour de la commande

On peut regarder au passage le code retour de cette commande

nowwecode:~$ echo $?
2

0 veut dire que tout va bien, n'importe quel autre chiffre veut dire qu'il y a une erreur. Ici, 2 signifie qu'il y a une erreur.

Récupérer uniquement la sortie standard (stdout)

nowwecode:~$ ls hello.txt goodbye.txt 2> /dev/null
hello.txt

On redirige la sortie 2 (sortie d'erreur) vers /dev/null

/dev/null sur Linux est un fichié spécial. Il supprime tout ce qui est écrit dedans et renvoie EOF à la lecture.
Il agit comme un trou noir, qui aspire tout ce qu'on lui envoie.

Récupérer uniquement la sortie d'erreur standard (stderr)

nowwecode:~$ ls hello.txt goodbye.txt 1> /dev/null
ls: cannot access 'goodbye.txt': No such file or directory

Avec des fichiers

Écrire stdout dans un fichier

nowwecode:~$ ls hello.txt goodbye.txt 1> output.txt
ls: cannot access 'goodbye.txt': No such file or directory

Ou

nowwecode:~$ ls hello.txt goodbye.txt > output.txt
ls: cannot access 'goodbye.txt': No such file or directory

On peut aussi chainer pour ne plus afficher l'erreur

nowwecode:~$ ls hello.txt goodbye.txt 1> output.txt 2> /dev/null

Ajouter stdout à la fin d'un fichier

nowwecode:~$ ls hello.txt goodbye.txt 1>> output.txt
ls: cannot access 'goodbye.txt': No such file or directory

Ou

nowwecode:~$ ls hello.txt goodbye.txt >> output.txt
ls: cannot access 'goodbye.txt': No such file or directory

Écrire stderr dans un fichier

nowwecode:~$ ls hello.txt goodbye.txt 2> output.txt
hello.txt

Ajouter stderr à la fin d'un fichier

nowwecode:~$ ls hello.txt goodbye.txt 2>> output.txt
hello.txt

Bonus: Allons plus loin

Écrire stdout et stderr dans un fichier

nowwecode:~$ ls hello.txt goodbye.txt &> output.txt

& désigne les deux sorties standard 1 et 2.

Ou

nowwecode:~$ ls hello.txt goodbye.txt > output.txt 2>&1

2>&1 veut dire rediriger 2 là ou est 1.

Ajouter stdout et stderr à la fin d'un fichier

nowwecode:~$ ls hello.txt goodbye.txt &>> output.txt

Ou

nowwecode:~$ ls hello.txt goodbye.txt >> output.txt 2>&1

Ajouter stdout et stderr dans un fichier et les afficher dans le terminal

nowwecode:~$ ls hello.txt goodbye.txt 2>&1 | tee output.txt
ls: cannot access 'goodbye.txt': No such file or directory
hello.txt