voyant très souvent cette commande j’ai voulu en savoir un peu plus . Basiquement c’est assez simple sauf que je bute sur un exmple précis qui me bloque :
mm@Xfce:~$ rm . .. 2>t.txt | cat t.txt
pourtant t.txt n’est pas vide puisque
mm@Xfce:~$ cat t.txt
rm: impossible de supprimer '.': est un dossier
rm: impossible de supprimer '..': est un dossier
par contre dans l’exemple ci-dessous la sortie est correcte
La partie rm qu’on a pas en entier envoie les éventuels retours d’affichage dans le fichier t.txt.
Le cat affichant le contenu.
en fait c’est inélégant, car inutile, les affichages provoqués par rm sont directement visible, donc pas besoin de les envoyer dans un fichier pour immédiatement l’afficher.
je ne sais pas où tu as trouvé ça, mais ça ne se fait pas vraiment.
les 2 lignes de commande sont faites maison , pas étonnant que ça pique pour un professionnel . Leur unique but : essayer les 2 commandes | et cat avec en plus la sortie du fichier stderr que je viens de découvrir , alors je me suis servi de la 1ère commande récente qui m’a sorti une erreur et qui m’est venue à l’esprit .
et ce que j’ai trouvé bizarre c’est que si je redirige la sortie de stdout ça fonctionne :
mm@Xfce:~$ rm . .. 1> t.txt | cat t.txt
rm: impossible de supprimer '.': est un dossier
rm: impossible de supprimer '..': est un dossier
mais bon c’est juste par curiosité , je ne vais pas me focaliser là-dessus .
Ça dépends de ce que tu veux dire par : ça fonctionne
rm . .. 1> t.txt | cat t.txt
Dans le cas de la ligne de commandes ci-dessus, comme le message d’erreur retourné dans le flux stderr par la commande rm n’est plus redirigé, il s’affiche dans la console.
Mais le fichier t.txt sera vidé de ce qu’il contenait (s’il contenait déjà autre chose)
puisque le flux stdout de la commande rm n’aura rien retourné.
pour être sûr je vais supprimer le fichier avant de réessayer :
mm@Xfce:~$ rm t.txt
mm@Xfce:~$ rm . .. 1> t1.txt | cat t1.txt
rm: impossible de supprimer '.': est un dossier
rm: impossible de supprimer '..': est un dossier
ok , voilà l’explication = concaténation . 1&2 en somme . J’ai vu passer un truc comme ça dans une page sur ces fichiers virtuels . Je n’avais pas du tout compris la 1ère réponse de @anon29980398 .
Tout à fait.
Le contenu de t1.txt est écrasé par la sortie standard (vide) de la commande rm. Et cat concatène ensuite t2 avec l’erreur standard de la commande rm
Il me semble que ton problème vient (entre autres) de l’utilisation du pipe avec les redirections. Ce qui n’a pas l’air trivial à part pour stdout.
Tu peux lire cette page, c’est intéressant (et pas simple).
Il y est dit que :
Le stdin du côté droit du pipe ‹ | › prend toujours sa source du stdout du côté gauche
Et donc si je comprends bien, quand tu tapes :
rm . .. 2>t.txt | cat t.txt
Il n’y a rien dans le stdout du côté gauche, et donc le pipe ne peut fonctionner. De plus, si tu cherches à enchaîner deux commandes, ce n’est pas un pipe (|) qu’il faut utiliser, mais un point-virgule ( :
effectivement ça n’a pas l’air évident évident et je vais laisser ça de côté car de toute façon ces fichiers virtuels ne me sont pas du tout indispensables : je connais leur existence et ça suffira .
en conclusion : pour tester ces deux commandes c’était l’exemple à ne surtout pas choisir . pff…
merci pour l’info .
Dans ce contexte, le tiret représente l’entrée standard :
michel@deb114x:~$ echo "contenu de t1.txt" > t1.txt
michel@deb114x:~$ echo "t2.txt vers stdin de la commande qui sera après le pipe => sera remplacé par le tiret" > t2.txt
michel@deb114x:~$ cat t1.txt
contenu de t1.txt
michel@deb114x:~$ cat t2.txt
t2.txt vers stdin de la commande qui sera après le pipe => sera remplacé par le tiret
michel@deb114x:~$ #############################################
michel@deb114x:~$
michel@deb114x:~$ cat t2.txt | cat t1.txt
contenu de t1.txt
michel@deb114x:~$
michel@deb114x:~$ cat t2.txt | cat
t2.txt vers stdin de la commande qui sera après le pipe => sera remplacé par le tiret
michel@deb114x:~$
michel@deb114x:~$ #############################################
michel@deb114x:~$ cat t2.txt | cat - t1.txt
t2.txt vers stdin de la commande qui sera après le pipe => sera remplacé par le tiret
contenu de t1.txt
michel@deb114x:~$
michel@deb114x:~$ cat t2.txt | cat t1.txt -
contenu de t1.txt
t2.txt vers stdin de la commande qui sera après le pipe => sera remplacé par le tiret
michel@deb114x:~$
cat ne concatène rien du tout. Comme l’a écrit @anon29980398, il affiche le contenu du fichier passé en argument. L’affichage des messages d’erreurs est dû à la sortie d’erreur de rm qui n’est pas redirigée.
J’ajoute que, dans la ligne de commandes suivante :
rm . .. 2>t.txt | cat t.txt
le pipe connecte :
le flux stdout de la commande rm
au flux stdin de la commande cat
Le pipe ne prends pas en compte le flux stderr de la commande rm
Mais, dans ce contexte ( …impossible de supprimer …) :
La commande rm ne retourne rien du tout par son flux stdout => donc la commande pipe n’aura rien à transmettre au flux stdin de la commande cat
de plus, pour que la commande cat lise son flux stdin il faudrait qu’on ne lui ait donné aucun nom de fichier, ou bien qu’on lui spécifie de lire aussi son flux stdin en ajoutant un tiret dans la liste des noms de fichiers à concaténer.
même si je ne comprends pas pourquoi la transmission des flux se passe ainsi , ça explique le résultat observé . Trop de trous dans la raquette pour que je sois capable de suivre le chemin emprunté par les flux de données . Sans le savoir j"ai visé trop haut .
Mais en séparant les flux je vois mieux ce qu’il se passe , transmissions avec pipe non comprises :
mm@Xfce:~$ rm . .. 1>t1.txt 2>t2.txt
mm@Xfce:~$ cat t1.txt
mm@Xfce:~$ cat t2.txt
rm: impossible de supprimer '.': est un dossier
rm: impossible de supprimer '..': est un dossier
Je pense que c’est plutot rm quelquechose 2> /tmp/glop || cat /tmp/glop
qui efface le qquelkquechose et affiche les erreurs si il y en a eu tout en les conservant dans un fichier.