Як запустити час на декілька команд І записати час, який виводиться у файл?


65

Я хочу запустити 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"'
Гео

7

Спробуйте це:

% (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. Можливо, башизм?
Джош

@josch використовувана тут оболонка zsh.
angus

6

Не правильна відповідь, але дуже пов'язана з питанням.
Отримати статистику хронометражу для декількох програм комбінованих дужок потрібно. Відокремте команди з крапками з комою.

time ( command1 ; command2 )

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