afficher les STDOUT avant STDERR?

9

Je suis nouveau à bash et je ne peux pas pour la vie de moi comprendre comment exécuter une certaine commande, supposer ./fffet imprimer des stdouts réguliers avant stderr (je suis confus quant au sens moi-même)

par exemple

$ printf "I am a\ndrill\n" > fff; 
$ cat fff nofile fff nofile fff

I am a
drill
cat: nofile: No such file or directory
I am a
drill
cat: nofile: No such file or directory
I am a
drill

doit imprimer comme:

I am a
drill
I am a
drill
I am a
drill
cat: nofile: No such file or directory
cat: nofile: No such file or directory

Je comprends que je dois d'abord rediriger ma sortie vers un fichier, puis ajouter l'erreur au même fichier, mais c'est la sortie que j'obtiens pour

$ cat ./foo nofile ./foo nofile ./foo <<< $(touch fin) > see 2>> see 

I am a
drill
I am a
drill
I am a
drill
ectory
cat: nofile: No such file or directory
Miaou
la source
2
A catvraiment remplacé "a" par "certains"?
Dmitry Grigoryev
oh dang je pourrais avoir foiré la chaîne. Je vais l'éditer tout de suite @DmitryGrigoryev
MeOw

Réponses:

18

Vous devrez de toute façon conserver la sortie stderr pour pouvoir l'afficher à la fin.

Un dossier me vient à l'esprit:

fff 2> file; cat file >&2

Ou la mémoire (ici à spongepartir de moreutils):

{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
  • {...} 3>&1: Dans le {...}descripteur de fichier (fd) 3 points à la même ressource que l' originale stdout (afin que nous puissions l' utiliser pour restaurer stdout pour fff).
  • fff <redirs> | sponge <redirs>, fffet a spongecommencé simultanément (avec <redirs>appliqué indépendamment) avec fffstdout allant vers un tube et spongestdin étant l'autre extrémité du tube.
  • 2>&1: fd 2 de fff(stderr) pointe vers la même chose que sur 1: le tuyau à ce point, donc fffl'erreur passe spongepar ce tuyau.
  • >&3: maintenant stdout pointe vers la stdout d'origine (redirige vers ce qu'elle était)
  • 3>&-: on ferme fd 2 qui fffn'a pas besoin
  • spongeaccumule son entrée et l'affiche uniquement (sur sa sortie standard qui a été redirigée >&2vers la même ressource que stderr) après avoir détecté eof sur fffsa sortie standard (supposé être à la fin et a déjà écrit toutes ses sorties sur sa sortie standard).

Si spongen'est pas installé, vous pouvez le remplacer par perl -0777 -pe ''. Avec -pe '', perllit un enregistrement à la fois à partir de son entrée et l'écrit sur stdout. -0777est le mode slurp où l'enregistrement (un seul dans ce cas) est l'entrée entière.

Stéphane Chazelas
la source
S'il vous plaît veuillez le décomposer si vous avez le temps!
George Udosen
Pouvons-nous utiliser teeau lieu de sponge...?
George Vasiliou
@GeorgeUdosen voir modifier.
Stéphane Chazelas
1
@GeorgeVasiliou, teene détient pas de données, il les écrit dès qu'il les lit.
Stéphane Chazelas
2
@MeOw: C'est bien, mais, comme le montre la troisième ligne de la réponse de Stéphane, vous n'avez pas besoin de sauvegarder la sortie standard; fais juste cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txt. (Et vous ne voulez probablement pas utiliser >>.) De plus, Stéphane fait le point excellent que vous devriez probablement faire cat ferr.txt >&2pour écrire les informations stderr dans le stderr.
G-Man dit `` Réintègre Monica '' le