$ # 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>&14>&2
$ time=$(TIMEFORMAT="%R";{ time ls 1>&32>&4;}2>&1)
bar baz
$ exec 3>&-4>&-
Время будет выглядеть как «0,000», используя TIMEFORMAT="%R"реальное время.
Приостановлено до дальнейшего уведомления. источник
Не могли бы вы немного объяснить, как это работает? Я использую фрагмент, подобный этому стилю грузового культа, годами. Что такое поток 3 и 4? и "-"?
Sirex
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'.
Я заинтересован в том, чтобы сделать это без -o. Можете ли вы опубликовать один из причудливых методов, о которых вы думали :)?
Дэвид Дория
0
Ответ @Dennis Williamson отличный, но он не поможет вам сохранить выходные данные команды в одной переменной, а выходные данные - timeв другой переменной. На самом деле это невозможно при использовании файловых дескрипторов.
Если вы хотите записать, сколько времени занимает запуск программы, вы можете сделать это, просто вычтя время начала из времени окончания. Вот простой пример, который показывает, сколько миллисекунд потребовалось программе для запуска:
time
; Ответ Денниса Уильямсона лучше в этом отношении.Смотрите BashFAQ / 032 .
Время будет выглядеть как «0,000», используя
TIMEFORMAT="%R"
реальное время.источник
exec
командой в моем ответе с использованием доступных файловых дескрипторов. Можно использовать любые доступные файловые дескрипторы. Потоки 3 и 4 являются копиями 1 (stdout
) и 2 (stderr
) соответственно. Это позволяетls
нормально передавать выходные данные вstdout
иstderr
через 3 и 4, в то время как выходные данныеtime
(которые обычно идут вstderr
) перенаправляются в исходное состояниеstdout
(1) и затем записываются в переменную с помощью подстановки команд. Как вы можете видеть в моем примере, имена файловbar
иbaz
выводятся на терминал. ...-
.Время записывает свой вывод в STDERR, а не в STDOUT. Что еще хуже, по умолчанию 'time' является встроенной командой оболочки, поэтому, если вы попытаетесь 'time ls 2> & 1', '2> & 1' будет применяться только к 'ls'.
Решение, вероятно, будет что-то вроде:
Есть более причудливые способы сделать это, но это ясный / простой способ.
источник
Ответ @Dennis Williamson отличный, но он не поможет вам сохранить выходные данные команды в одной переменной, а выходные данные -
time
в другой переменной. На самом деле это невозможно при использовании файловых дескрипторов.Если вы хотите записать, сколько времени занимает запуск программы, вы можете сделать это, просто вычтя время начала из времени окончания. Вот простой пример, который показывает, сколько миллисекунд потребовалось программе для запуска:
Это не так точно, как
time
команда, но она должна прекрасно работать для большинства скриптов bash.К сожалению,
date
команда Mac не поддерживает%N
формат, но вы можете установитьcoreutils
(brew install coreutils
) и использоватьgdate
:источник