Auteur Message
Administrateur
Avatar de l’utilisateur
Je résume et je donne le lien qui en dit plus, à la fin.

Directement, la solution


Pour appliquer le filtre « filtre et ses arguments » sur le flux d’erreur de la commande « commande et ses arguments », on peut penser naïvement à :

Code : 

commande-et-ses-arguments 2| filtre-et-ses-arguments

Cette manière, pourtant la plus intuitive, ne fonctionne pas, il faut faire à la place :

Code : 

{
exec 3>&1;
{
commande-et-ses-arguments \
2>&1 1>&3 \
| filtre-et-ses-arguments;
} \
3>&1 1>&2;
exec 3>&-;
}

Remarques :
  • Le slash dans `} \`, à la septième ligne, est important. Sans lui, les redirections qui le suivent le sont pas appliquées.
  • L’ordre des redirections, `2>&1 1>&3`, à la cinquième ligne, est important. Si vous faites `1>&3 2>&1` à la place, ça ne marchera pas correctement.

C’est un peu plus compliqué, mais ça marche. Franchement, si les concepteurs des shells Bash et Sh avaient pensé à ce cas de figure, ça n’aurait pas été un luxe inutile.

Example pratique


Soit la commande Tidy. Elle renvoie les messages d’erreur sur le flux stderr. Elle le fait dans un format qui n’est pas standard, dont voici un example :

Code : 

line 12 column 17 - Warning: trimming empty <style>

Il manque le nom de fichier, le numéro de colonne n’est pas compris par la plupart des application, et le numéro de ligne n’est pas écrit sous la forme standard `:nn:`.
Il faudrait donc pouvoir arriver à :

Code : 

fichier.html:12: Warning: trimming empty <style>

Avec le filtre Sed, ce n’est pas compliqué, mais comme Tidy renvoie les messages d’erreur sur le flux stderr au lieu du flux stdout, il n’est pas possible de le faire simplement avec un pipe, et il faut appliquer la méthode indiquée plus haut, ce qui donne :

Code : 

# FILE_BASE_NAME, FILE_EXTENSION et FILE_PATH, sont
# censés être définis pendant une étape précédente.

N="$FILE_BASE_NAME.$FILE_EXTENSION"
{
exec 3>&1;
{
tidy -quiet --markup no "$FILE_PATH" \
2>&1 1>&3 \
| sed -e "s/line \([0-9]\+\) column [0-9]\+ -/$N:\1:/g"
} \
3>&1 1>&2;
exec 3>&-;
}


Origine de l’astuce et détails


Comme Google ne sait pas lire, il ne donne pas toujours la meilleure place dans ses résultats, à ce qui répond le mieux à une question, je donne le lien : Utiliser le pipe sur stderr (linux-attitude.fr).

Questions ?


S’il y a des questions, il ne faut pas se priver pour les poser Clin d’œil .
Profil