Redirection de sortie partielle

Le
Francois Lafont
Bonjour à tous,

Je suis sous Debian Squeeze. Je butte sur un truc assez basique mais qui
m'intrigue et que je ne comprends pas. Voici ce que me donne la commande
ci-dessous :

--
# aptitude update -v
Atteint http://ftp2.fr.debian.org squeeze Release.gpg
Ign http://ftp2.fr.debian.org/debian/ squeeze/contrib Translation-en
Ign http://ftp2.fr.debian.org/debian/ squeeze/contrib Translation-fr
Atteint http://www.debian-multimedia.org squeeze Release.gpg

[Couic]

Atteint http://ftp2.fr.debian.org squeeze-updates/main amd64 Packages

État actuel : 0 paquet cassé [+0], 0 mise à jour restante [+0], 276
nouveaux paquets [+0].
#
--

Très bien, j'ai en sortie la dernière ligne que je voudrais isoler avec
un grep. Je tente alors ça :

--
# aptitude update -v | grep 'État actuel'
#
--

Aucune sortie. Je tente une redirection vers un fichier :

--
# aptitude update -v > out
--

Et dans le fichier out je retrouve toute la sortie que j'avais dans la
première commande, sauf la fameuse derrière ligne. Ok, là je me dis, sûr
de moi, c'est bon je sais ce qu'il se passe : la dernière ligne provient
du flux de sortie des erreurs standard (stderr) et non du flux de sortie
standard (stdout), alors je tente ça :

--
# aptitude update -v 2>&1 1> out
--

Et bien dans le fichier out, toujours pas cette fameuse dernière ligne.
Mais elle provient d'où alors cette dernière ligne si elle ne provient
ni de stdout et ni de stderr ? Comment faire pour la récupérer elle et
elle seule J'aimerais bien comprendre.

Merci d'avance pour votre aide.

--
François Lafont
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 4
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Benoit Izac
Le #24169091
Bonjour,

le 16/01/2012 à 18:49, Francois Lafont a écrit dans le message

-----------------------------------------------------------
# aptitude update -v 2>&1 1> out
-----------------------------------------------------------



Là tu rediriges stderr à l'endroit où se trouve stdout (le terminal dans
lequel tu es) puis tu rediriges stdout (pas ce que tu as redirigé
auparavant) dans le fichier out.

atitude update -v >out 2>&1

Là ça redirige stdout dans le fichier out puis stderr dans stdout (le
fichier out).

--
Benoit Izac
Luc.Habert.00__arjf
Le #24169141
1) export LC_ALL=C pour avoir des messages sans accents, ça dégage déjà une
source de confusion possible. (Je ne pense pas que ce soit ça, mais ça ne
mange pas de pain.)
2) si c'est pas stderr vs stdout, ça pourrait etre une histoire de
buffering, sauf que ton aptitude a l'air de se terminer avant que tu
regardes le contenu du fichier.
3) aptitude pourrait regarder si son stdout pointe sur un terminal et
afficher plus de messages dans ce cas. (Ça fait chier les programmes qui
veulent etre trop intelligents.)
Francois Lafont
Le #24169131
Le 16/01/2012 19:01, Benoit Izac a écrit :

-----------------------------------------------------------
# aptitude update -v 2>&1 1> out
-----------------------------------------------------------



Là tu rediriges stderr à l'endroit où se trouve stdout (le terminal dans
lequel tu es) puis tu rediriges stdout (pas ce que tu as redirigé
auparavant) dans le fichier out.



Alors, j'ai bien fait de poser la question car j'ai appris quelque
chose. Donc, si je suis bien ce que tu me dis, l'ordre dans lequel on
précise les redirection compte, c'est ça ? ceci :

# commande 2>&1 1> out

serait finalement équivalent à cela :

# commande 1> out

C'est bien ça ?

atitude update -v >out 2>&1

Là ça redirige stdout dans le fichier out puis stderr dans stdout (le
fichier out).



Ok. Et bien soit. Mais même de cette manière j'ai toujours le même
problème : je ne retrouve pas la fameuse ligne dans le fichier out.


--
François Lafont
Benoit Izac
Le #24169171
Bonjour,

le 16/01/2012 à 19:12, Francois Lafont a écrit dans le message

Alors, j'ai bien fait de poser la question car j'ai appris quelque
chose. Donc, si je suis bien ce que tu me dis, l'ordre dans lequel on
précise les redirection compte, c'est ça ? ceci :

# commande 2>&1 1> out

serait finalement équivalent à cela :

# commande 1> out

C'est bien ça ?



Oui puisque par défaut stderr est redirigé vers stdout.

% cat abcd >/dev/null
cat: abcd: No such file or directory
% cat abcd >/dev/null 2>&1
% cat abcd 2>&1 >/dev/null
cat: abcd: No such file or directory

Ok. Et bien soit. Mais même de cette manière j'ai toujours le même
problème : je ne retrouve pas la fameuse ligne dans le fichier out.



Je passe.

--
Benoit Izac
Francois Lafont
Le #24169161
Le 16/01/2012 19:04, Luc Habert a écrit
:
1) export LC_ALL=C pour avoir des messages sans accents, ça dégage déjà une
source de confusion possible. (Je ne pense pas que ce soit ça, mais ça ne
mange pas de pain.)



Oui le problème ne vient pas de là, mais merci pour le coup du :

LC_ALL=C aptitude update -v

car effectivement les accents sont une source d'embrouilles alors ce
truc là, je vais le retenir.

Si je comprends bien la variable d'environnement LC_ALL défnie la
langue, mais à quoi correspond la valeur « C » ?

2) si c'est pas stderr vs stdout, ça pourrait etre une histoire de
buffering, sauf que ton aptitude a l'air de se terminer avant que tu
regardes le contenu du fichier.



Pas sûr d'avoir compris ce que tu veux dire. J'ouvre mon fichier out une
fois la commande terminée. Ça serait possible que « ça » continue à
écrire dans le fichier alors que la commande est terminée et que j'ai le
prompt ? Si oui, à quoi correspondrait « ça » ?

3) aptitude pourrait regarder si son stdout pointe sur un terminal et
afficher plus de messages dans ce cas. (Ça fait chier les programmes qui
veulent etre trop intelligents.)



Ah peut-être, j'ai un peu pensé à un truc dans le genre. Et comment en
shell bash par exemple on fait pour savoir si stdout pointe sur un
terminal ou non ? Je serais curieux de le savoir. Y a-t-il une variable
d'environnement à tester ? Auquel cas on pourrait peut-être leurrer la
commande.


--
François Lafont
Luc.Habert.00__arjf
Le #24169201
Francois Lafont :

Si je comprends bien la variable d'environnement LC_ALL défnie la
langue,



Pour une bonne définition de langue. Le terme technique est locale, ce qui
inclue la langue des messages, mais plein d'autres chose, comme l'encodage,
l'ordre des caractères, le . vs , dans les floats et bien d'autres
cochonneries dont j'ai parfois l'impression qu'elles ont été inventées dans
le seul but de semer des bugs partout. Il y a des variables d'environnement
pour régler indépendament chacun de ces paramètres (LC_MESSAGES) pour la
langue et deux variables qui s'appliquent à tous: LC_LANG et LC_ALL. LC_ALL
a priorité sur les paramètres individuels qui ont priorité sur LC_LANG. Je
t'ai dit LC_ALL plutot que LC_MESSAGES histoire de ne pas avoir à digresser
sur le fait que si tu as un LC_ALL, mettre un LC_MESSAGES ne servira à rien.

mais à quoi correspond la valeur « C » ?



En gros, ça veut dire une locale la plus simple possible, donc en anglais,
ascii, comparaison des caractères dans l'ordre ascii, ...

Pas sûr d'avoir compris ce que tu veux dire. J'ouvre mon fichier out une
fois la commande terminée. Ça serait possible que « ça » continue à
écrire dans le fichier alors que la commande est terminée et que j'ai le
prompt ?



Non, à moins qu'aptitude forke un fils détaché du terminal, mais c'est peut
probable. Je disais juste ça par automatisme "dernière ligne manquante ->
elle est encore dans le buffer".

Et comment en shell bash par exemple on fait pour savoir si stdout pointe
sur un terminal ou non ?



Il y a la commande tty qui done le terminal vers lequel pointe son stdin et
rale sinon. Sous linux, c'est implémenté tout betement en lisant le symlink
/proc/self/fd/0. Sous d'autres OS, ça peut se faire avec un fstat(0), tu
regardes le st_rdev et tu regardes si ça correspond à un /dev/tty*.
Francois Lafont
Le #24169381
Le 16/01/2012 19:20, Benoit Izac a écrit :

Alors, j'ai bien fait de poser la question car j'ai appris quelque
chose. Donc, si je suis bien ce que tu me dis, l'ordre dans lequel on
précise les redirection compte, c'est ça ? ceci :

# commande 2>&1 1> out

serait finalement équivalent à cela :

# commande 1> out

C'est bien ça ?



Oui puisque par défaut stderr est redirigé vers stdout.

% cat abcd >/dev/null
cat: abcd: No such file or directory
% cat abcd >/dev/null 2>&1
% cat abcd 2>&1 >/dev/null
cat: abcd: No such file or directory



Ok, donc si j'ai bien compris « 2>&1 » redirige stderr vers non pas vers
« stdout » mais vers « le fichier sur lequel stdout *à l'instant donné*
». La valeur de &1 peut être différente sur une même ligne suivant
qu'elle est appelée avant ou après la redirection de stdout.
Franchement, je ne savais pas.



--
François Lafont
Francois Lafont
Le #24170281
Le 16/01/2012 19:41, Luc Habert a écrit :

Si je comprends bien la variable d'environnement LC_ALL défnie la
langue,



Pour une bonne définition de langue. Le terme technique est locale, ce qui
inclue la langue des messages, mais plein d'autres chose, comme l'encodage,
l'ordre des caractères, le . vs , dans les floats et bien d'autres
cochonneries dont j'ai parfois l'impression qu'elles ont été inventées dans
le seul but de semer des bugs partout. Il y a des variables d'environnement
pour régler indépendament chacun de ces paramètres (LC_MESSAGES) pour la
langue et deux variables qui s'appliquent à tous: LC_LANG et LC_ALL. LC_ALL
a priorité sur les paramètres individuels qui ont priorité sur LC_LANG. Je
t'ai dit LC_ALL plutot que LC_MESSAGES histoire de ne pas avoir à digresser
sur le fait que si tu as un LC_ALL, mettre un LC_MESSAGES ne servira à rien.

mais à quoi correspond la valeur « C » ?



En gros, ça veut dire une locale la plus simple possible, donc en anglais,
ascii, comparaison des caractères dans l'ordre ascii, ...



Ok, c'est très clair. Vraiment, je le retiens celui-là.

Pas sûr d'avoir compris ce que tu veux dire. J'ouvre mon fichier out une
fois la commande terminée. Ça serait possible que « ça » continue à
écrire dans le fichier alors que la commande est terminée et que j'ai le
prompt ?



Non, à moins qu'aptitude forke un fils détaché du terminal, mais c'est peut
probable. Je disais juste ça par automatisme "dernière ligne manquante ->
elle est encore dans le buffer".



Oui je comprends. Mais effectivement c'est hautement peu probable dans
le cas de la commande aptitude.

Et comment en shell bash par exemple on fait pour savoir si stdout pointe
sur un terminal ou non ?



Il y a la commande tty qui done le terminal vers lequel pointe son stdin et
rale sinon. Sous linux, c'est implémenté tout betement en lisant le symlink
/proc/self/fd/0. Sous d'autres OS, ça peut se faire avec un fstat(0), tu
regardes le st_rdev et tu regardes si ça correspond à un /dev/tty*.



Je pense que mon souci provient sans doute d'un truc du genre : suivant
où est redirigé stdout, aptitude n'affiche pas exactement la même chose.
En tout cas, c'est la seule explication que je vois pour l'instant...

Merci pour ton aide Luc.

--
François Lafont
Luc.Habert.00__arjf
Le #24170271
Pour en avoir le coeur net :

strace -o /tmp/ploum1 aptitude update

et

strace -o /tmp/ploum2 aptitude update > /tmp/ploum3

et comparer /tpm/ploum[12].
Emmanuel Florac
Le #24170851
Le Tue, 17 Jan 2012 02:26:00 +0100, Francois Lafont a écrit:


Je pense que mon souci provient sans doute d'un truc du genre : suivant
où est redirigé stdout, aptitude n'affiche pas exactement la même chose.



Il existe en effet pas mal de programmes, par exemple ls, qui vérifient
si leur STDOUT est un terminal ou pas, et qui modifient leur comportement
en conséquence. Je ne sais pas si c'est le cas pour aptitude mais c'est
possible.

--
When the people fears the government, there is tyranny; when the
government fears the people, there is liberty.
Thomas Jefferson.
Publicité
Poster une réponse
Anonyme