Поскольку POSIX определяет утилиту time для записи своего результата при стандартной ошибке, вам нужно знать только о том, что существует встроенная bash
time
, которая ведет себя немного по-другому .
$ time sleep 1
real 0m1.004s
user 0m0.001s
sys 0m0.002s
$ time sleep 1 2>xyz
real 0m1.005s
user 0m0.001s
sys 0m0.003s
$ (time sleep 1) 2>xyz
$ cat xyz
real 0m1.005s
user 0m0.001s
sys 0m0.002s
$ /usr/bin/time sleep 1 2>xyz
$ cat xyz
1.00 real 0.00 user 0.00 sys
$
Тестирование показано на MacOS X 10.7. Обратите внимание на разницу в формате вывода между встроенной и внешней версиями команды time
. Также обратите внимание, что в формате под-оболочки встроенный time
перенаправляется нормально, но в простом случае перенаправление вывода после встроенного time
не отправляет вывод в то же место, где остальные стандартной ошибки идет в.
Итак, эти наблюдения позволяют вам написать свой элегантный сценарий. Вероятно, самый простой способ - обернуть существующий скрипт как функцию, а затем вызвать эту функцию через встроенный time
.
Оригинальный сценарий
# This is what was in the Exp script before.
# It echoes its name and its arguments to both stdout and stderr
echo "Exp $*"
echo "Exp $*" 1>&2
Пересмотренный скрипт
log=./Exp.log
Exp()
{
# This is what was in the Exp script before.
# It echoes its name and its arguments to both stdout and stderr
echo "Exp $*"
echo "Exp $*" 1>&2
}
(time Exp "$@") 2>> $log
Обратите внимание на осторожное использование "$@"
при вызове функции Exp
для сохранения отдельных аргументов, передаваемых в командной строке, и одинаково преднамеренное использование $*
внутри функции ( который теряет отдельные аргументы, но только для иллюстративных целей).
Возможная проблема
Единственная проблема, связанная с этим, заключается в том, что выходные данные об ошибках исходной команды также передаются в тот же файл журнала, что и информация о времени. Это может быть решено, но включает в себя хитрое многократное перенаправление , которое скорее запутает, чем поможет. Однако, к сведению, это прекрасно работает:
log=./Exp.log
Exp()
{
# This is what was in the Exp script before.
# It echoes its name and its arguments to both stdout and stderr
echo "Exp $*"
echo "Exp $*" 1>&2
}
exec 3>&2
(time Exp "$@" 2>&3 ) 2>> $log