Comment puis-je rediriger la sortie `time` et la sortie de la commande vers le même canal?

24

Supposons que j'ai un binaire appelé foo.

Si je veux rediriger la sortie de foovers un autre processus bar, je pourrais écrire ./foo | bar.

D'autre part, si je voulais timefoo, et rediriger la sortie que timeje pourrais écrire, time (./foo) | bar.

Ma question est, comment puis-je coller la sortie de timeà la fin de la sortie de fooet la diriger à travers le même tuyau ?

La solution suivante n'est pas celle que je recherche, car elle démarre deux instances distinctes du processus bar, alors que je veux un seul canal partagé, vers une seule instance de bar.

time (./foo | bar)  | bar

Pour tous ceux qui sont curieux, la raison de ne pas vouloir démarrer deux instances de barest parce que barpeut être un client réseau et je veux que les informations de synchronisation soient envoyées au serveur dans le cadre du même http POSTmessage que la sortie du processus.

merlin2011
la source
répondu ici, réponse un peu meilleure: stackoverflow.com/questions/13356628/…
JDS

Réponses:

30

Si je comprends ce que vous demandez, je le ferai. J'utilise les commandes ls ~et teecomme remplaçants pour ./fooet bar, mais la forme générale de ce que vous voulez est la suivante:

$ ( time ./foo ) |& bar

REMARQUE: La sortie de timeest déjà attachée à la fin de toute sortie de ./foo, elle est en train de le faire sur STDERR. Pour le rediriger à travers le tube, vous devez combiner STDERR avec STDOUT. Vous pouvez utiliser soit |&ou 2>&1pour le faire.

$ ( time ./foo ) |& bar

-or-

$ ( time ./foo ) 2>&1 | bar

Exemple

$ ( time ls . ) |&  tee cmd.log
cmd.log
file1
file2
file3
file4
file5

real    0m0.005s
user    0m0.000s
sys     0m0.001s

Et voici le contenu du fichier cmd.log produit par tee.

$ more cmd.log 
cmd.log
file1
file2
file3
file4
file5

real    0m0.005s
user    0m0.000s
sys     0m0.001s
slm
la source
Notez que cette syntaxe ne fonctionne pas pour BASH.
jvriesem
1
@jvriesem tous les exemples sont de bash
slm
9

timeenvoie sa sortie à stderr au lieu de stdout par défaut. Vous avez juste besoin de rediriger cela où vous le souhaitez.

Vous dites "d'autre part, si je voulais timetromper et rediriger la sortie detime je pourrais écrire,. time (./foo) | bar" mais c'est en fait incorrect. Dans ce cas, la sortie de l'heure serait toujours affichée sur votre console, seule la sortie standard serait redirigée.

Vous pouvez rediriger stderr spécifiquement avec:

(time foo) 2>&1 | bar

ou tous les tuyaux avec:

(time foo) |& bar

Les supports sont nécessaires pour que cela fonctionne correctement.

Émeute
la source
0

J'ai trouvé que cela fonctionne sur Solaris. (time ls) &> file

anisbet
la source
1
Ce n'est pas différent de l'une des solutions existantes
roaima