Як перенаправити висновок команди часу на файл у Linux?


202

Лише невелике запитання щодо програм синхронізації в Linux: команда time дозволяє виміряти час виконання програми:

[ed@lbox200 ~]$ time sleep 1

real    0m1.004s
user    0m0.000s
sys     0m0.004s

Що чудово працює. Але якщо я спробую перенаправити вихід у файл, він не вдається.

[ed@lbox200 ~]$ time sleep 1 > time.txt

real    0m1.004s
user    0m0.001s
sys     0m0.004s

[ed@lbox200 ~]$ cat time.txt 
[ed@lbox200 ~]$ 

Я знаю, що існують інші реалізації часу з опцією -o написати файл, але моє питання стосується команди без цих параметрів.

Будь-які пропозиції ?


3
Можливий дублікат bash script запису часу виконання у файл , і я далеко не переконаний, що це перше таке питання.
Джонатан Леффлер

Відповіді:


266

Спробуйте

{ time sleep 1 ; } 2> time.txt

який поєднує STDERR "time" та вашу команду в time.txt

Або використовувати

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

який ставить STDERR з "сну" у файл "sleep.stderr" і лише STDERR з "time" переходить у "time.txt"


2
Дякую, що відповідає саме на моє запитання. Якщо я правильно зрозумів, результат команди команди можна отримати від stderr?
ed82

7
Так, але ви повинні помістити його у фігурні дужки, інакше перенаправлення буде частиною команди, що timeоцінює.
січня

5
@Daniel Ви завжди можете перенаправляти внутрішній вивід команди окремо (тобто {time sleep 1 2> sleepStdErr.txt;} 2> time.txt), і це отримає лише вихідний час. Я не впевнений, чи є спосіб отримати самостійно інакше.
gms7777

10
Якщо ви хочете використати час з чимось на зразок grep, який зачитує stdout, спробуйте { time sleep 1; } 2>&1 | grep real. Це надсилає stderr до stdout, який може потім прочитати grep.
clayzermk1

9
НЕ забудьте ';' символу перед закриттям "}", він НЕ буде працювати без (я це зробив, і ... цікаво, чому не працює :))
THESorcerer

38

Оберніть timeта команду, яку ви розміщуєте в наборі дужок.

Наприклад, наступні рази lsі записує результат lsта результати хронометражу в outfile:

$ (time ls) > outfile 2>&1

Або, якщо ви хочете відокремити вихід команди від захопленого виводу від time:

$ (time ls) > ls_results 2> time_results

12
Тут не потрібно вводити нижню частину корпусу.
січня

1
@ sampson-chen Це працює лише тому, що ls нічого не пише stderr правильно? Як би ви «відокремили» висновок 'time' від виведення команди, якщо команда записує як stdout, так і stderr?
Девід Дорія

36

Простий. timeУтиліта GNU має для цього можливість.

Але ви повинні переконатися, що ви не використовуєте вбудовану timeкоманду вашої оболонки , принаймні bashвбудований не забезпечує цей варіант! Ось чому вам потрібно дати повний шлях timeутиліти:

/usr/bin/time -o time.txt sleep 1

Ви також можете використовувати не вбудований, не вказуючи повний шлях: stackoverflow.com/questions/29540540 / ...
Чіро Сантіллі郝海东冠状病六四事件法轮功

14

Якщо вам важлива помилка виводу команди, ви можете їх розділити так, використовуючи вбудовану команду часу.

{ time your_command 2> command.err ; } 2> time.log

або

{ time your_command 2>1 ; } 2> time.log

Як ви бачите помилки команди, перейдіть до файлу (оскільки stderrвикористовується для time).

На жаль, ви не можете надіслати його на іншу ручку (наприклад 3>&2), оскільки вона більше не буде існувати поза межами{...}

Однак, якщо ви можете скористатися часом GNU, просто зробіть те, що сказав @Tim Ludwinski.

\time -o time.log command

8

Оскільки вихід команди 'time' є вихідною помилкою, перенаправлення її як стандартного виводу буде більш інтуїтивно зрозумілою для подальшої обробки.

{ time sleep 1; } 2>&1 |  cat > time.txt

6

Якщо ви використовуєте час GNU замість вбудованого bash, спробуйте

time -o outfile command

(Примітка. Формат часу GNU трохи інакше, ніж вбудований bash).


1
Це, дякую. І ви можете використовувати \time -o outfile command(з ``) для використання GNU замість вбудованого.
Позначте

3
&>out time command >/dev/null

у вашому випадку

&>out time sleep 1 >/dev/null

тоді

cat out

3
Елегантна ідея, але призводить до того, що оболонка не використовує вбудовану команду. Якщо у вас немає справжнього timeбінарного файлу, він outбуде містити щось на зразок bash: time: command not found.
scy

Також формат часу GNU не такий, як bash вбудований, що створює проблеми для автоматичного розбору.
Гасс

3

Я закінчив використовувати:

/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
  • Де додається "а"
  • Якщо "o" переходить до імені файлу, до якого потрібно додати
  • Де "f" - формат із синтаксисом, схожим на printf
  • Де "% E" виробляє 0:00:00; годин: хвилин: секунд
  • Мені довелося викликати / usr / bin / time, тому що bash "time" топтав його і не має однакових варіантів
  • Я просто намагався отримати вихід у файл, не те саме, що в ОП

2
#!/bin/bash

set -e

_onexit() {
    [[ $TMPD ]] && rm -rf "$TMPD"
}

TMPD="$(mktemp -d)"
trap _onexit EXIT

_time_2() {
    "$@" 2>&3
}

_time_1() {
    time _time_2 "$@"
}

_time() {
    declare time_label="$1"
    shift
    exec 3>&2
    _time_1 "$@" 2>"$TMPD/timing.$time_label"
    echo "time[$time_label]"
    cat "$TMPD/timing.$time_label"
}

_time a _do_something
_time b _do_another_thing
_time c _finish_up

Це має перевагу від нерестування підкорпусів, і в кінцевому трубопроводі він буде більш жорстким відновленим до реального.


0

Якщо ви не хочете торкатися початкового процесу 'stdout та stderr, ви можете перенаправити stderr на дескриптор файлу 3 і назад:

$ { time { perl -le "print 'foo'; warn 'bar';" 2>&3; }; } 3>&2 2> time.out
foo
bar at -e line 1.
$ cat time.out

real    0m0.009s
user    0m0.004s
sys     0m0.000s

Ви можете використовувати це для обгортки (наприклад, для кронштейну) для моніторингу виконання:

#!/bin/bash

echo "[$(date)]" "$@" >> /my/runtime.log

{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log

0

Якщо ви використовуєте, cshви можете використовувати:

/usr/bin/time --output=outfile -p $SHELL  -c 'your command'

Наприклад:

/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.