Как перенаправить вывод команды времени в файл в 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 записывает время выполнения в файл , и я далеко не убежден, что это первый такой вопрос.
Джонатан Леффлер

Ответы:


267

Пытаться

{ time sleep 1 ; } 2> time.txt

который объединяет STDERR «времени» и вашу команду в time.txt

Или использовать

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

который помещает STDERR из «сна» в файл «sleep.stderr» и только STDERR из «времени» переходит в «time.txt»


2
Спасибо, что отвечает именно на мой вопрос. Если я правильно понял, результат команды времени можно получить из stderr?
ed82

8
Да, но вы должны поместить его в фигурные скобки, в противном случае перенаправление будет частью команды, которая 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/…
Ciro Santilli 4 冠状 病 六四 事件 法轮功

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, что вызывает проблемы при автоматическом разборе.
Guss

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" его растоптал и у него не было таких же опций
  • Я просто пытался получить вывод в файл, а не то же самое, что OP

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

Преимущество этого заключается в том, что не создаются субоболочки, и в конечном конвейере его stderr восстанавливается до реального stderr.


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

Вы можете использовать это для оболочки (например, для cronjobs) для мониторинга времени выполнения:

#!/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.