redirection entree sortie

Le
vraifaux
Bonjour,

J'ai un répertoire /travail qui est vide.

je fais
1)rmdir aa > /dev/null 2>&1
et rien ne s'affiche à l'écran

j'essaie de comprendre :
D'abord l'instruction rmdir aa >/dev/ null semble envoyer la sortie ecran à
la corbeille mais n'en fait pas de même pour la sortie erreur qui s'affiche
à l'écran.

Or 2>&1 redirige 2 vers l'écran, aussi je ne comprends pas que rien
s'affiche à la fin de 1)


ensuite je fais
2)rmdir aa 2>&1 > /dev/null
et s'affiche alors " rmdir : aa :Aucun fichier ou répertoire de ce type."

J'essaie de comprendre :
rmdir aa 2>&1 redirige 2 vers 1 donc le message d'erreur vers la sortie
écran
et > /dev/null envoie cette sortie à la corbeille. Aussi je ne comprends
pas que dans ce cas un message d'erreur apparaisse.

Je me doute que cette question est bien connue et malgré mes recherches avec
google et les livres
Linux Redhat Fedora (700 pages) je n'arrive pas à éclaircir ce mystère.
Merci mille fois à celui qui saura m'expliquer ces redirections qui me
paraissent obscures.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Cumbalero
Le #20115491
vraifaux a écrit :
Bonjour,

J'ai un répertoire /travail qui est vide.

je fais
1)rmdir aa > /dev/null 2>&1
et rien ne s'affiche à l'écran

j'essaie de comprendre :
D'abord l'instruction rmdir aa >/dev/ null semble envoyer la sortie ec ran à
la corbeille mais n'en fait pas de même pour la sortie erreur qui s'a ffiche
à l'écran.




Tu devrais bannir le mot "corbeille". C'est redirigé vers "le rien".

Je résume très synthétiquement et te laisse lire la doc pour approf ondir.

Il existe 3 flux qui permettent la communication entre le système et to i:

- l'entrée (stdin, identifiée 0). Par défaut, c'est le clavier, mai s tu
peux la rediriger de 3 façons: la redirection (en utilisant < pour
prendre un fichier en entrée), le pipe (pour que la sortie standard d'u n
process soit prise en entrée d'un autre), le "here document" (en
utilisant <<)

- la sortie standard (stdout, identifiée 1). Par défaut c'est l'écr an.
Elle affiche la sortie des commandes. Tu peux la rediriger vers un
fichier (en utilisant > ou >>) ou vers l'entrée d'une autre commande en
utilisant le pipe ou -

le sortie d'erreur (stderr, identifiée 2). Par défaut c'est l'écran . Tu
peux la rediriger vers un fichier en utilisant > ou >>.


rmdir aa > monfic.txt est équivalent à rmdir aa 1> monfic.txt : le
fichier contiendra les messages normaux de la commande (la liste des
fichiers si tu fais un ls).

rmdir aa 2> monfic.txt : le fichier contiendra les messages d'erreurs
renvoyés par la commande.

rmdir aa 2>&1: les messages d'erreurs sont renvoyés vers la sortie
standard. Si cette sortie standard a été redirigée, la sortie d'err eur
le sera aussi.

Linux Redhat Fedora (700 pages) je n'arrive pas à éclaircir ce myst ère.



Soit tu as mal regardé, soit ce n'est pas le livre qu'il te faut... Ce
sont les bases du système Unix.


A+
JF
Eric Dorino
Le #20116861
On Fri, 11 Sep 2009 08:26:45 +0200, vraifaux wrote:

Bonjour,i, 11 Sep 2009 08:26:45 +0200, vraifaux wrote:



Bonjour,



Bonjour,


J'ai un répertoire /travail qui est vide.

je fais


[snip]




:~/Essais/xxx$ rmdir aa 2>&1 >/dev/null
rmdir: failed to remove `aa': No such file or directory
:~/Essais/xxx$ rmdir aa >/dev/null 2>&1


Je me doute que cette question est bien connue et malgré mes recherches
avec google et les livres
Linux Redhat Fedora (700 pages) je n'arrive pas à éclaircir ce mystère.
Merci mille fois à celui qui saura m'expliquer ces redirections qui me
paraissent obscures.



(Je suppose que le shell est bash).
man bash, chercher ^REDIRECTION donne la solution, qui est liée à l'ordre
d'évaluation des redirections (de gauche à droite).


--
Eric
vraifaux
Le #20117591
votre réponse :
rmdir aa 2>&1: les messages d'erreurs sont renvoyés vers la sortie
standard. Si cette sortie standard a été redirigée, la sortie d'erreur
le sera aussi.

ma réponse:

Merci beaucoup pour le temps consacré à ma question.
Malgré la doc je ne comprends pas pourquoi

rmdir aa 2>&1 > /dev/null

retourne " rmdir : aa :Aucun fichier ou répertoire de ce type."


En effet le message d'erreur due à l'absence du répertoire aa est redirigé
vers l'écran
qui lui même est redirigé vers le rien.
Donc pourquoi est retourné " rmdir : aa :Aucun fichier ou répertoire de ce
type."
C'est cela le mystère pour moi.
Merci pour votre patience.
Fabien LE LEZ
Le #20118511
On Fri, 11 Sep 2009 13:30:53 +0200, "vraifaux"
rmdir aa 2>&1 > /dev/null



En effet le message d'erreur due à l'absence du répertoire aa est redirigé
vers l'écran
qui lui même est redirigé vers le rien.



Je peux me gourer, mais il me semble que les deux redirections sont
indépendantes (et non pas successives comme tu t'y attends).

Ainsi, ce que le programme envoie sur stderr (2) est transféré sur
stdout (1). Indépendamment de ça, ce que le programme renvoie sur
stdout part dans le vide. Mais comme rmdir n'envoie rien sur stdout,
rien n'est envoyé dans le vide.

Plutôt qu'utiliser rmdir, si tu as gcc, utilise ce code (qui affiche
"stdout(1)" sur stdout et "stderr(2)" sur stderr) :

#include
int main()
{
puts ("stdout(1)n");
fputs ("stderr(2)n", stderr);
}

Enregistre ces sept lignes dans un fichier test.c, puis tape
gcc -o test test.c

et enfin, teste avec :

./test
./test 2>&1 1>/dev/null
Lucas Levrel
Le #20119041
Le 11 septembre 2009, Eric Dorino a écrit :
man bash, chercher ^REDIRECTION donne la solution, qui est liée à l'ordre
d'évaluation des redirections (de gauche à droite).



J'ai toujours eu du mal avec les redirections. Je trouve que dire qu'elles
sont évaluées de gauche à droite ne suffit pas.

Si on interprète les redirections comme un entonnoir (ce que le >
suggère !), alors on a l'impression qu'avec :
2&>1 1>/dev/null
on envoie la sortie 2 dans le bac 1 puis on jette le bac 1 (qui contient
maintenant 1+2) dans le vide...

Pour comprendre ce qui se passe en réalité, on peut considérer chaque
redirection comme une instruction à interpréter au fur et à mesure :
- 2&>1 : à ce stade 1 conduit à l'écran, donc ceci donne stderr->écran ;
- 1>/dev/null : stdout->le vide

Inversement, 1>/dev/null 2&>1 donne :
- 1>/dev/null : stdout->le vide ;
- 2&>1 : 1 conduit au vide, donc cela donne stderr->le vide

--
LL
Nicolas George
Le #20119321
Lucas Levrel wrote in message
J'ai toujours eu du mal avec les redirections. Je trouve que dire qu'elles
sont évaluées de gauche à droite ne suffit pas.

Si on interprète les redirections comme un entonnoir



On se vautre. Si on interprète les redirections comme ce qu'elles sont,
c'est à dire l'accès à dire un open ou un dup2 :

« > /dev/null », implicitement « 1> /dev/null » : branche 1 sur /dev/null

« 2>&1 » : branche 2 sur la même chose que 1
Fabien LE LEZ
Le #20119511
J'ai écrit :
Je peux me gourer, mais il me semble que les deux redirections sont
indépendantes



Ben apparemment, je me suis effectivement gouré.
En revanche, le code que je t'ai donné sera plus pratique que rmdir
pour tester.
vraifaux
Le #20120591
D'abord merci à tous ceux qui essaient de m'expliquer.


Eric Dorino écrit :

<<(Je suppose que le shell est bash).
man bash, chercher ^REDIRECTION donne la solution, qui est liée à l'ordre
d'évaluation des redirections (de gauche à droite).>>

Faites vous allusion à :
Note that the order of redirections is significant. For example, the

command

ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist,

while the command

ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the standard

error was duplicated as standard output before the standard output was

redirected to dirlist.

?Merci à ceux qui pourraient développer car mon anglais est faible.

Par ailleurs Lucas Levrel écrit

<<Si on interprète les redirections comme un entonnoir (ce que le >
suggère !), alors on a l'impression qu'avec :
2&>1 1>/dev/null
on envoie la sortie 2 dans le bac 1 puis on jette le bac 1 (qui contient
maintenant 1+2) dans le vide...

Pour comprendre ce qui se passe en réalité, on peut considérer chaque
redirection comme une instruction à interpréter au fur et à mesure :
- 2&>1 : à ce stade 1 conduit à l'écran, donc ceci donne stderr->écran ;
- 1>/dev/null : stdout->le vide

Inversement, 1>/dev/null 2&>1 donne :
- 1>/dev/null : stdout->le vide ;
- 2&>1 : 1 conduit au vide, donc cela donne stderr->le vide>>

LL dit notamment :
- 2&>1 : à ce stade 1 conduit à l'écran, donc ceci donne stderr->écran ;
1>/dev/null : stdout->le vide

mais comme ecran est 1, il va dans vide, l'affichage final est vide alors
qu'en réalité il y a un message.
C'est vraiment incompréhensible pour moi.
Merci pour votre patience.
Eric Dorino
Le #20121001
On Fri, 11 Sep 2009 18:50:53 +0200, vraifaux wrote:

D'abord merci à tous ceux qui essaient de m'expliquer.



Pas de quoi.



Eric Dorino écrit :

<<(Je suppose que le shell est bash).
man bash, chercher ^REDIRECTION donne la solution, qui est liée à
l'ordre d'évaluation des redirections (de gauche à droite).>>

Faites vous allusion à :
Note that the order of redirections is significant. For example, the

command



[snip]




Oui.


?Merci à ceux qui pourraient développer car mon anglais est faible.

Par ailleurs Lucas Levrel écrit

<<Si on interprète les redirections comme un entonnoir (ce que le >



Surtout pas.

[snip]

mais comme ecran est 1, il va dans vide, l'affichage final est vide
alors qu'en réalité il y a un message.
C'est vraiment incompréhensible pour moi. Merci pour votre patience.



(En supposant un shell dans un fenêtre X):
La situation de départ:
stdout (fd 1) sur /dev/pts/42
stderr (fd 2) sur /dev/pts/42

En spécifiant ls 2>&1 >/dev/null:
- on duplique le fd 1 et on l'assigne au fd 2 (ce qui ne change rien);
- on assigne /dev/null sur stdout;
stdout (fd 1) sur /dev/null
stderr (fd 2) sur /dev/pts/42
et les erreurs vont sur le terminal.

En spécifiant ls >/dev/null 2>&1:
- on assigne /dev/null sur stdout.
stdout (fd 1) sur /dev/null
stderr (fd 2) sur /dev/pts/42
- on duplique le fd 1 et on l'assigne au fd 2;
stdout (fd 1) sur /dev/null
stderr (fd 2) sur /dev/null
et le programme est muet.

--
Eric
Nicolas George
Le #20121761
"vraifaux" wrote in message
on duplique le fd 1 et on l'assigne au fd 2 ?



Un programme Unix manipule les fichiers par le biais de file descriptors
(fd), de petits entiers qui servent au noyau d'index pour des structures de
données.

Un file descriptor pointe vers un élément « description », qui correspond
plus directement au fichier ou pseudo-fichier (extrémité de pipe, device)
lui-même.

Plusieurs file descriptors peuvent pointer sur la même description. Le noyau
garde le compte, pour chaque description, du nombre de file descriptors qui
pointent dessus. Quand ce nombre tombe a zéro, il supprime la description.

L'appel système open crée une description pour le fichier indiqué, puis
trouve le premier file descriptor libre, et le fait pointer sur cette
description.

L'appel système close(X) vide le file descriptor X. Ce qui peut avoir pour
conséquence de supprimer la description correspondante.

L'appel système dup2(X, Y) commence par faire comme close(Y), puis copie le
file descriptor X dans le file descriptor Y.

Quand on écrit « X> foo », le shell commence par faire un open("foo"), et
obtient un filedescriptor Y qui pointe vers une description correspondant au
fichier foo. Ensuite, si X est différent de Y, le shell fait un dup2(Y, X),
de sorte que maintenant, le file descriptor X pointe vers la description de
foo. Enfin, il appelle close(Y).

Quand on écrit « X>&Y », le shell fait un dup2(Y, X).

Dernier point : quand on a « foo | bar », le shell appelle pipe pour obtenir
une paire de file descriptors X et Y qui correspondent à une paire de
descriptions qui sont les extrémités d'un pipe. Puis il se scinde en deux
processus. Dans celui de gauche, il ferme le file descriptor X de lecture,
puis se débrouille avec fup2 et close pour que le file descriptor Y
d'écriture devienne 1. Idem dans le processus de droite, il ne garde que le
file descriptor X de lecture et se débrouille pour qu'il devienne 0. Ceci se
produit _avant_ de commencer à faire les redirections décrites dans foo.
Donc quand on a un pipe, la redirection correspondant au pipe, bien
qu'apparaissant tout à droite de la commande de gauche, intervient en
premier.

Maintenant, je conseille à tous ceux qui m'ont suivi jusque là de prendre un
papier et un stylo, ou mieux un tableau, et de faire des schémas, avec des
carrés à droite pour les descriptions, des ronds à gauche pour les
file descriptors et des flèches entre, pour comprendre des redirections
compliquées.
Publicité
Poster une réponse
Anonyme