Как я могу перенаправить вывод `time` и вывод команды на один и тот же канал?

24

Предположим, у меня есть бинарный файл foo.

Если я хочу перенаправить вывод какого- fooлибо другого процесса bar, я мог бы написать ./foo | bar.

С другой стороны, если бы я хотел timeобув, и перенаправить вывод timeя мог бы написать, time (./foo) | bar.

Мой вопрос, как я могу прикрепить вывод timeдо конца вывода fooи направить его через ту же трубу ?

Следующее решение - не то, что я ищу, потому что оно запускает два отдельных экземпляра процесса bar, а я хочу один общий канал для одного экземпляра bar.

time (./foo | bar)  | bar

Любой, кому любопытно, не хочет запускать два экземпляра, barпотому что barможет быть сетевым клиентом, и я хочу, чтобы информация о синхронизации была отправлена ​​на сервер как часть того же http POSTсообщения, что и выходные данные процесса.

merlin2011
источник
ответил здесь, несколько лучше ответ: stackoverflow.com/questions/13356628/…
JDS

Ответы:

30

Если я пойму, о чем ты просишь, я это сделаю. Я использую команды ls ~и в teeкачестве замены для ./fooи bar, но общая форма того, что вы хотите, это:

$ ( time ./foo ) |& bar

ПРИМЕЧАНИЕ . Выходные данные timeуже подключены в конце любого выходного файла ./foo, просто это делается на STDERR. Чтобы перенаправить его через канал, вам нужно объединить STDERR с STDOUT. Вы можете использовать либо |&или 2>&1сделать это.

$ ( time ./foo ) |& bar

-or-

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

пример

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

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

А вот содержимое файла, cmd.logсозданного tee.

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

real    0m0.005s
user    0m0.000s
sys     0m0.001s
SLM
источник
Обратите внимание, что этот синтаксис не работает для BASH.
jvriesem
1
@jvriesem все примеры взяты из bash
slm
9

timeпо умолчанию отправляет свой вывод в stderr вместо stdout. Вам просто нужно перенаправить туда, куда вы хотите.

Вы говорите: «С другой стороны, если бы я захотел timefoo и перенаправил вывод, timeя мог бы написать time (./foo) | bar». но это на самом деле неверно. В этом случае вывод времени будет по-прежнему отображаться на вашей консоли, перенаправляется только стандартный вывод.

Вы можете перенаправить stderr специально с:

(time foo) 2>&1 | bar

или все трубы с:

(time foo) |& bar

Скобки необходимы для того, чтобы это работало правильно.

буйство
источник
0

Я обнаружил, что это работает на Solaris. (time ls) &> file

anisbet
источник
1
Это ничем не отличается от любого из существующих решений
roaima