Есть ли способ найти время выполнения последней выполненной команды в оболочке? - PullRequest
23 голосов
/ 24 апреля 2010

Существует ли такая команда, как time, которая может отображать сведения о времени выполнения последних или последних выполненных команд в оболочке?

Ответы [ 5 ]

13 голосов
/ 24 апреля 2010

Я не знаю, как в bash, но в zsh вы можете определить функции preexec и precmd, чтобы они сохраняли текущее время в переменных $STARTTIME (preexec) и $ENDTIME (precmd) так что вы сможете найти примерное время работы. Или вы можете определить функцию accept-line так, чтобы она предшествовала time перед каждой командой.

UPDATE : Это код, который будет хранить прошедшее время в массиве $_elapsed:

preexec () {
   (( $#_elapsed > 1000 )) && set -A _elapsed $_elapsed[-1000,-1]
   typeset -ig _start=SECONDS
}
precmd() { set -A _elapsed $_elapsed $(( SECONDS-_start )) }

Тогда, если вы запустите sleep 10s:

% set -A _elapsed # Clear the times
% sleep 10s
% sleep 2s ; echo $_elapsed[-1]
10
% echo $_elapsed
0 10 0

Нет необходимости в четырех переменных. Никаких проблем с именами или дополнительными задержками. Просто обратите внимание, что массив $_elapsed может стать очень большим, поэтому вам необходимо удалить первые элементы (это делается с помощью следующего фрагмента кода: (( $#_elapsed > 1000 )) && set -A _elapsed $_elapsed[-1000,-1]).

UPDATE2 : Нашел скрипт для поддержки zsh-style precmd и preexec в bash. Возможно, вам нужно будет удалить typeset -ig (я использовал просто, чтобы $_start был целым числом) и заменить set -A var ... на var=( ... ), чтобы это работало. И я не знаю, как нарезать массивы и получить их длину в bash.

Сценарий: http://www.twistedmatrix.com/users/glyph/preexec.bash.txt

Update3 : Обнаружил одну проблему: если вы нажмете return с пустой строкой, preexec не запустится, а precmd - запустит, поэтому вы получите бессмысленные значения в массиве $_elapsed. Чтобы это исправить, замените функцию precmd следующим кодом:

precmd () {
   (( _start >= 0 )) && set -A _elapsed $_elapsed $(( SECONDS-_start ))
   _start=-1 
}
5 голосов
/ 24 апреля 2010

Редактировать 3:

Структура этого ответа:

  1. Не существует готового способа измерения времени для команды, которая уже была выполнена
  2. Существуют способы, позволяющие вывести приблизительную оценку продолжительности времени выполнения команды.
  3. Показано доказательство концепции (начиная с гипотезы, что это невозможно сделать, и заканчивая выводом о том, что гипотеза ошибочна).
  4. Существуют хаки, которые вы можете поставить на место заранее, которые будут записывать прошедшее время каждой команды, которую вы запускаете
  5. Заключение

Ответ, помеченный его частями в соответствии с приведенным выше планом:

Часть 1 - краткий ответ «нет»

Оригинал

Нет, извините. Вы должны использовать time.

Часть 2 - может быть, вы можете вывести результат

В некоторых случаях, если программа записывает выходные файлы или информацию в файлы журналов, вы можете определить время выполнения, но это будет зависеть от программы и является лишь приблизительным. Если в Bash установлен HISTTIMEFORMAT, вы можете просмотреть записи в файле истории, чтобы получить представление о том, когда была запущена программа. Но время окончания не записывается, поэтому вы можете определить продолжительность только в том случае, если другая программа была запущена сразу после той, которая вас интересует.

Часть 3 - гипотеза опровергнута

Гипотеза : Время простоя будет учитываться в прошедшем времени

Edit:

Вот пример, иллюстрирующий мою точку зрения. Он основан на предложении ZyX , но будет аналогичен другим методам.

В zsh:

% precmd() { prevstart=start; start=$SECONDS; }
% preexec() { prevend=$end; end=$SECONDS; }
% echo "T: $SECONDS ps: $prevstart pe: $prevend s: $start e: $end"
T: 1491 ps: 1456 pe: 1458 s: 1459 e: 1491

Теперь мы ждем ... скажем, 15 секунд, затем:

% echo "T: $SECONDS"; sleep 10
T: 1506

Теперь мы ждем ... скажем, 20 секунд, затем:

% echo "T: $SECONDS ps: $prevstart pe: $prevend s: $start e: $end"
T: 1536 ps: 1492 pe: 1506 s: 1516 e: 1536

Как видите, я был неправ . Время начала (1516) минус предыдущее время окончания (1506) составляет длительность команды (sleep 10). Что также показывает, что переменным, которые я использовал в функциях, нужны более точные имена.

Гипотеза сфальсифицирована - это можно получить правильное истекшее время без учета времени простоя

Part 4 - хак для записи прошедшего времени каждой команды

Редактировать 2:

Вот эквиваленты Bash для функций в ответе ZyX (для них требуется скрипт, связанный с ним):

preexec () {
   (( ${#_elapsed[@]} > 1000 )) && _elapsed=(${_elapsed[@]: -1000})
   _start=$SECONDS
}

precmd () {
   (( _start >= 0 )) && _elapsed+=($(( SECONDS-_start )))
   _start=-1 
}

После установки preexec.bash (из связанного скрипта) и создания двух функций, приведенных выше, пример запуска будет выглядеть следующим образом:

$ _elapsed=() # Clear the times
$ sleep 10s
$ sleep 2s ; echo ${_elapsed[@]: -1}
10
$ echo ${_elapsed[@]}
0 10 2

часть 5 - заключение

Используйте time.

4 голосов
/ 03 июля 2012

Я так понимаю, вы запускаете команды, которые занимают много времени и в начале не понимают, что вы хотели бы определить время, которое требуется для их завершения.В zsh, если для переменной среды REPORTTIME задано число, любая команда, занимающая больше этого количества секунд, будет печатать время, которое вы печатали, как если бы вы выполняли ее с командой time перед ней.Вы можете установить его в вашем .zshrc так, чтобы у длительно работающих команд всегда было напечатано их время.Обратите внимание, что время, проведенное во сне (в отличие от времени пользователя / системы), не учитывается при срабатывании таймера, но все еще отслеживается.

3 голосов
/ 21 февраля 2016

Мир мог бы немного измениться, поскольку другие люди ответили на эти вопросы.

zsh имеет некоторые встроенные функции для определения времени выполнения команд.

Если вы включите опцию inc_append_history_time с

setopt inc_append_history_time

Затем время, затраченное на выполнение каждой команды, сохраняется в вашей истории и затем может быть просмотрено с помощью history -D.

1 голос
/ 24 апреля 2010

Я думаю, вы можете получить статистику по времени только для тех команд, которые вы запускаете, используя команду 'time'.

со страницы руководства:

время [опции] команда [аргументы ...]

ОПИСАНИЕ Команда time запускает указанную программную команду с заданными аргументами. Когда команда заканчивается, time пишет сообщение о стандартной ошибке, предоставляя статистику по времени выполнения этой программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...