Как запустить время по нескольким командам И записать вывод времени в файл?


66

Я хочу запустить timeкоманду, чтобы измерить время нескольких команд.

Что я хочу сделать, это:

  • Измерьте время прохождения всех их, сложенных вместе
  • Записать timeвывод в файл
  • Напишите STDERRиз команды, которую я измеряюSTDERR

Чего я не хочу делать, так это

  • Запишите несколько команд в отдельный скрипт (почему? Потому что все это уже сценарий, который я генерирую программно, и создание ДРУГОГО временного сценария будет более беспорядочным, чем я хочу)

Что я пробовал до сих пор:

/usr/bin/time --output=outtime -p echo "a"; echo "b";

Не работает, timeзапускается только на первом.

/usr/bin/time --output=outtime -p ( echo "a"; echo "b"; )

Не работает, (неожиданный токен.

/usr/bin/time --output=outtime -p { echo "a"; echo "b"; }

Не работает, "нет такого файла или каталога".

/usr/bin/time --output=outtime -p ' echo "a"; echo "b";'

Не работает, "нет такого файла или каталога".

time ( echo "a"; echo "b"; ) 2>outtime

Не работает, так как перенаправляет все STDERRв outtime; Я хочу только timeвывод там.

И, конечно же,

time --output=outime echo "a";

С тех пор не работает --output=outime: command not found.

Как я могу это сделать?

Ответы:


90

Используйте sh -c 'commands'в качестве команды, например:

/usr/bin/time --output=outtime -p sh -c 'echo "a"; echo "b"'

2
более короткая версия:time -p sh -c 'echo "a"; echo "b"'
Geo

8

Попробуй это:

% (time ( { echas z; echo 2 } 2>&3 ) ) 3>&2 2>timeoutput
zsh: command not found: echas
2
% cat timeoutput                                
( { echas z; echo 2; } 2>&3; )  0.00s user 0.00s system 0% cpu 0.004 total

Объяснение:

Во-первых, мы должны найти способ перенаправить вывод time. Поскольку timeэто встроенная оболочка, в качестве команды для измерения она принимает полную командную строку, включая перенаправления. Таким образом,

% time whatever 2>timeoutput
whatever 2> timeoutput  0.00s user 0.00s system 0% cpu 0.018 total
% cat timeoutput 
zsh: command not found: whatever

[Примечание: комментарий janos подразумевает, что это не так bash.] Мы можем добиться перенаправления timeвывода, запустив timeв подоболочке оболочку, а затем перенаправив вывод этого подоболочки.

% (time whatever) 2> timeoutput
% cat timeoutput 
zsh: command not found: whatever
whatever  0.00s user 0.00s system 0% cpu 0.018 total

Теперь мы успешно перенаправили вывод time, но его вывод смешивается с выводом ошибки команды, которую мы измеряем. Чтобы разделить их, мы используем дополнительный файловый дескриптор.

На "снаружи" мы имеем

% (time ... ) 3>&2 2>timeout

Это означает, что все, что записано в файловый дескриптор 3, будет выведено в то же место, что и файловый дескриптор 2 (стандартная ошибка), который выводится сейчас (терминал). И тогда мы перенаправляем стандартную ошибку в файл timeout.

Итак, теперь мы имеем: все, что записано в stdout и fd 3, будет отправлено в терминал, а все, что записано в stderr, попадет в файл. Осталось перенаправить stderr измеренной команды на fd 3.

% (time whatever 2>&3) 3>&2 2>timeout

Теперь, чтобы измерить время более чем одной командой, нам нужно запустить их в (другой!) Подоболочке (внутри скобок). И чтобы перенаправить вывод ошибок всех из них в fd 3, нам нужно сгруппировать их в фигурные скобки.

Итак, наконец, мы приходим к:

% (time ( { whatever; ls } 2>&3 ) ) 3>&2 2>timeoutput

Вот и все.


Это синтаксическая ошибка в оболочке POSIX. Вероятно, башизм?
17

@josch здесь используется оболочка zsh.
Ангус

6

Не правильный ответ, но очень связанный с вопросом.
Получить статистику по времени для нескольких программ, объединенных скобок не требуется. Разделяйте команды точкой с запятой.

time ( command1 ; command2 )

1
Это приятно. Еще лучше, используйте && между командами - так, time ( command1 && command2 )чтобы в случае неудачи первой команды; он не приступит к выполнению другого.
Бикашг
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.