Перенаправлення виводу команди time в unix на змінну в bash?


13

Я просто хочу зафіксувати вихід команди часу, тобто:

X=$(time ls)

або

$(time ls) | grep real

Функція часу, однак, плює його на консоль. Як це зробити?

Відповіді:


12

X = `(час ls) 2> & 1 | grep real`


Вам не потрібна передплатка лише для time; Відповідь Денніса Вільямсона в цьому плані краща.
musiphil

11

Див. BashFAQ / 032 .

$ # captures output of command and time
$ time=$( TIMEFORMAT="%R"; { time ls; } 2>&1 )    # note the curly braces

$ # captures the time only, passes stdout through
$ exec 3>&1 4>&2
$ time=$(TIMEFORMAT="%R"; { time ls 1>&3 2>&4; } 2>&1)
bar baz
$ exec 3>&- 4>&-

Час буде виглядати як "0,000", використовуючи TIMEFORMAT="%R"який буде "реальним" часом.


Ви могли б трохи пояснити, як це працює? Я використовую такий фрагмент, як цей вантажний культовий стиль роками. Що потік 3 і 4? і '-'?
Сірекс

1
@Sirex: Потоки 3 і 4 - це потоки, створені execкомандою у моїй відповіді, використовуючи доступні дескриптори файлів. Можуть бути використані будь-які доступні дескриптори файлів. Потоки 3 і 4 - це копії відповідно 1 ( stdout) і 2 ( stderr). Це дозволяє lsнормально переходити до stdoutта stderrчерез 3 і 4, тоді як вихід time(який зазвичай йде stderr) перенаправляється на оригінал stdout(1) і потім фіксується у змінній за допомогою підстановки команд. Як ви бачите в моєму прикладі, імена файлів barі bazвиводяться на термінал. ...
Призупинено до подальшого повідомлення.

1
... Після закінчення додаткові потоки закриваються за допомогою трейлінгу -.
Призупинено до подальшого повідомлення.

4

Час записує свій результат у STDERR, а не STDOUT. Що ще гірше, за замовчуванням "time" - це команда, вбудована в оболонку, тому якщо ви намагаєтеся "time ls 2> & 1", "2> & 1" застосовується лише до "ls".

Рішення, ймовірно, було б таким:

/usr/bin/time -f 'real %e' -o OUTPUT_FILE ls > /dev/null 2>&1<br>
REALTIME=$(cat OUTPUT_FILE | cut -f 2 -d ' ')

Є більш химерні способи зробити це, але це зрозумілий / простий спосіб.


Мені цікаво робити це без -о. Чи можете ви опублікувати один із фантазійних методів, про який ви думали :)?
Девід Дорія

0

@Денніс Вільямсон відповідь чудова, але це не допомагає вам зберігати результати команди в одній змінній, а вихід timeу іншій змінній. Це фактично неможливо за допомогою дескрипторів файлів.

Якщо ви хочете записати, скільки часу займає програма, ви можете це зробити, просто віднявши час початку від кінця. Ось простий приклад, який показує, скільки мілісекунд запустила програма:

START_TIME=$(date +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(date +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"

Це не так точно, як timeкоманда, але це повинно працювати чудово для більшості скриптів bash.

На жаль, dateкоманда Mac не підтримує %Nформат, але ви можете встановити coreutils( brew install coreutils) та використовувати gdate:

START_TIME=$(gdate +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(gdate +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.