Существует ли способ найти время выполнения последней выполняемой команды в оболочке?

Есть ли команда как time это может отобразить детали времени выполнения последнего или мимо выполняемых команд на оболочке?

24
задан Lambda 24 April 2010 в 13:37
поделиться

3 ответа

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

ОБНОВЛЕНИЕ : Это код, который сохранит истекшее время в массиве $ _ 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] ).

ОБНОВЛЕНИЕ 2 : Обнаружен сценарий, поддерживающий zsh-style Precmd и preexec в bash. Возможно, вам нужно будет удалить typeset -ig (я использовал только для того, чтобы заставить $ _ start быть целым числом) и заменить set -A var ... на var = (...) , чтобы это работало. И я не знаю, как разрезать массивы и получать их длину в bash.

Скрипт: http://www.twistedmatrix.com/users/glyph/preexec.bash.txt

UPDATE3 : Обнаружена одна проблема: если вы нажмете "возврат" с пустая строка preexec не запускается, в то время как Precmd запускается, поэтому вы получите бессмысленные значения в массиве $ _ elapsed . Чтобы исправить это, замените функцию precmd следующим кодом:

precmd () {
   (( _start >= 0 )) && set -A _elapsed $_elapsed $(( SECONDS-_start ))
   _start=-1 
}
13
ответ дан 29 November 2019 в 00:12
поделиться

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

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

time [параметры] команда [аргументы ...]

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

1
ответ дан 29 November 2019 в 00:12
поделиться

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

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

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

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

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

Оригинал

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

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

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

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

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

Изменить:

Вот пример, чтобы проиллюстрировать мою точку зрения. Он основан на предложении 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) составляет длительность команды ( спящий режим 10 ). Это также показывает, что переменные, которые я использовал в функциях, нуждаются в лучших именах.

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

Часть 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 - заключение

Используйте время .

5
ответ дан 29 November 2019 в 00:12
поделиться