Как скорректировать команду времени для измерения прошедшего времени программы

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

cat somefile | tr '\t' '  '

заменит символ табуляции двумя пробелами.

Обновление: как указано в комментариях к этому сообщению, это на самом деле не работает. Тем не менее, я сохраняю ответ как пример того, как не сделать это.

4
06.01.2013, 15:09
2 ответа

Если все, что Вы хотите, является прошедшим временем, то с zsh или ksh93:

$ typeset -F SECONDS=0; sleep 1; print "$SECONDS"
1.0012850761

Теперь, ли такая точность имеет смысл, другой вопрос.

5
27.01.2020, 20:48
  • 1
    +1 для опроса, действительно ли наличие более прекрасного, чем измерение мс разумно. –  peterph 10.11.2012, 01:42
  • 2
    Да это помогло мне определить, где я хотел добраться до! Благодарит Вас! –  Ini 15.11.2012, 18:00

Вычислительное время в наносекундах под GNU/Linux, использование .

ПРЕДУПРЕЖДЕНИЕ Этого сообщения было представлено устаревшее новым хорошим методом, обсужденным там: Профилирование удара (3 ответа) и с полным готовым к использованию исходным файлом там: Elap-удар V3

Способы получить надежные значения

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

Во-первых, но не лучше всего: 1/100-й из вторых

Для 1/100-го из вторых Вы могли просто обратиться к /proc/uptime:

sed 's/ .*$//' /proc/uptime 
276440.58

Смещение времени для добавления для вычисления реального времени UTC могло быть, получают одним из:

ps ho lstart 1 | date -f - +%s
1357193821

или

date +%s.%N-$(sed 's/ .*$//' /proc/uptime ) | bc -l
1357193821.088187101

Как смещение статичны, это значение могло быть вычислено в, только 1 раз, в начинаются сценария.

1/1000000000-й из секунд, с помощью proc записи только:

Для вычислений с наносекундами существует a proc entry, именованный /proc/timer_list которые содержат обоих uptime и offset:

sed < /proc/timer_list -ne '/now at/p;/offset/{p;q}'
now at 276350507668586 nsecs
  .offset:     1357193821075753443 nsecs

Так это

echo $(($(sed < /proc/timer_list -ne '
    /^now at/{s/now at \([0-9]*\) ns.*$/\1/;H};
    /offset/{s/^.*: *\([0-9]*\) ns.*$/\1/;G;s/\n\+/+/;p;q}'))) 
1357470173543424035

целое число наносекунд, истекших от 1970-1-1 00:00:00 UTC.

Для вычислительного целого числа под нет никакой потребности использовать bc и для парсинга proc файлы, мы могли использовать mapfile который является встроенным ударом:

# first, some static variables (with fork, but only 1 time, at begin;):
nowAtLine=$(($(sed -ne < /proc/timer_list '/now at/{=;q}')-1))
offset=$(sed -ne < /proc/timer_list '
    /offset/{s/^.*: *\([0-9]*\) n.*$/\1/p;q}')

# than this will be a lot quicker than a fork:
mapfile -n 1 -s $nowAtLine timerList </proc/timer_list &&
    timerList=($timerList) &&
    echo $((${timerList[2]}+offset))
1357470173543424035

1/1000000000-й из секунд, с помощью date двоичный инструмент:

И наконец если они не существуют, мы могли бы звонить date учет того факта, что это - a fork которые занимают намного больше времени, чем чтение proc files, пребывание только на одной сессии удара.

date +%s%N
1357470074808968375

Мой elap.bash функция

на основе этого я записал функцию удара elap с двумя счетчиками: 1 для каждого вызова и другого для своего рода overall duration.

Использование:

Во-первых, это - функция, не сценарий. Вы имеете к source их на Вашей текущей сессии удара для использования его.

. elap.bash
Syntaxe:
elap [ [ -r | -R ] | [ -n ] [ -t | -T ] [<simple text report>] ]
    -r reset first counter only, don't output anything, like -R...
    -R reset both counters, (both -r and -R must by unique argument)
    -n don't reset any counter (just print)
    -t print both counters (reset first counter)
    -T print and reset

Чем сброс оба счетчика перед использованием его:

elap -R
find /usr/bin >/dev/null
elap browsing /usr/bin

     0.025389543 browsing /usr/bin

Таким образом, Вы могли добавить некоторые маркеры в сценарии:

#!/bin/bash
. elap.bash
  elap -R
tar -cf /tmp/test.tar -C / bin
  elap making a tarball of $(stat -c %s /tmp/test.tar) bytes
gzip /tmp/test.tar
  elap compressing them to $(stat -c %s /tmp/test.tar.gz) bytes
scp /tmp/test.tar.gz backup@elswhere.net:backups/
  elap sending file to backup server
rm /tmp/test.tar.gz
  elap removing compressed tarball
elap -t total duration

     0.043223957 making a tarball of 5877760 bytes
     0.667249628 compressing them to 2742537 bytes
test.tar.gz                                  100% 2678KB 2.6MB/s 00:00
     0.380779818 sending file to backup server
     0.010262259 removing compressed tarball
     0.003566335      1.105081997 total duration

Используя trap debug поскольку пошаговое следование

С или без -t переключатель, с помощью trap debug для пошагового, остроумие меньше изменения сценария (добавил четыре строки наверху сценария и один в основе):

Как захватывающий для отладки будет occure прежде $BASH_COMMAND выполнение, мы должны сохранить переменное содержание к a $BASH_LAST переменная для корректной печати, и добавляет фиктивную команду в конце сценария.

#!/bin/bash

. elap.bash
elap -R
export BASH_LAST=Starting
trap 'elap -t $BASH_LAST;BASH_LAST=$BASH_COMMAND' debug 

tar -cf /tmp/test.tar -C / bin
gzip /tmp/test.tar
scp /tmp/test.tar.gz backup@elswhere.net:backups/
rm /tmp/test.tar.gz

exit $?

exit $? команда необходима для дампа statistiques после последнего rm команда.

     0.001011086      0.001011086 Starting
     0.045175969      0.046187055 tar -cf /tmp/test.tar -C / bin
     0.651394209      0.697581264 gzip /tmp/test.tar
test.tar.gz                                  100% 2678KB 2.6MB/s 00:00
     0.374499354      1.072080618 scp /tmp/test.tar.gz backup@elswhere.net:backups/
     0.007160101      1.079240719 rm /tmp/test.tar.gz

Функциональный источник

Где Вы могли сократить (или переупорядочивание) uptime часть, если Вы предпочитаете использовать ветвление для date +%s%N вместо того, чтобы использовать 1/100-й из гранулярности секунд.

#
# Bash source file for fine elapsed time reporting
# based on /proc/timer_list, display elapsed time in nanosecs
# or /proc/uptime if timer_list not present, for 100th of secs.
# if none of them if present, fall back to *fork* `date +%s%N`.
#
# (C) 2011-2012 Felix Hauri - felix@f-hauri.ch
# Licensed under terms of LGPL v3. www.gnu.org

# Usage:
#   load script into bash using ``source elap.bash''
#
# Syntaxe: elap [ [ -r | -R ] | [ -n ] [ -t | -T ] [<simple text report>] ]
#   -r reset first counter only, don't output anything, like -R...
#   -R reset both counters, (both -r and -R must by unique argument)
#   -n don't reset any counter (just print)
#   -t print both counters (reset first counter)
#   -T print and reset
#
# nota: using ``-n'' in combinaison with any of ``-r'' or ``-R'' is buggy.

export _elaP_now _elaP_last _elaP_elap _elaP_last2 _elaP_dec

if [ -r /proc/timer_list ] ;then
    _elaP_file=/proc/timer_list
    _elaP_dec=9
    _elaP_field=2
    mapfile < $_elaP_file _elaP_now
    _elaP_line=0
    while [ "${_elaP_now[_elaP_line]}" == \
    "${_elaP_now[_elaP_line]#*now at}" ] ;do
    ((_elaP_line++))
    done
    eval 'function elap_getNow() {
     mapfile -n 1 -s '$_elaP_line' <'$_elaP_file' _elaP_now
         _elaP_now=($_elaP_now)
         _elaP_now=${_elaP_now[_elaP_field]}
         }'
else
    #      --- To be removed for nanoseconds only
    if [ -r /proc/uptime ] ;then
    _elaP_dec=2
    function elap_getNow() {
        read -a _elaP_now </proc/uptime _elaP_now
            _elaP_now=${_elaP_now//./}
    }
    else # --- End of part to be removed for ns only.
    _elaP_dec=9
    function elap_getNow() { _elaP_now=$(date +%s%N) ;}
    fi   # --- Remove this line too for ns only.
fi

export -f elap_getNow

elap() {
    local _Z9=000000000
    local _elaP_setLast=true
    [ "$1" == "-n" ] && shift && _elaP_setLast=false
    [ "$2" == "-n" ] && set -- $1 ${@:3} && _elaP_setLast=false

    elap_getNow

    _elaP_elap=$((_elaP_now - _elaP_last))
    [ ${#_elaP_elap} -lt $_elaP_dec ] && \
    _elaP_elap=${_Z9:0:_elaP_dec-${#_elaP_elap}}$_elaP_elap
    [ "${*}" == "-R" ] &&  _elaP_last2=$_elaP_now || \
    [ "${*}" == "-r" ] || if [ "$1" == "-t" ] || [ "$1" == "-T" ] ;then
    local _elaP_setLast2=false
    [ "$1" == "-T" ] && _elaP_setLast2=true
    shift
            _elaP_elap2=$((_elaP_now - _elaP_last2))
    [ ${#_elaP_elap2} -lt $_elaP_dec ] && \
        _elaP_elap2="${_Z9:0:_elaP_dec-${#_elaP_elap2}}$_elaP_elap2"
        printf "%6d.%s %6d.%s %s\n" \
        "${_elaP_elap:0:${#_elaP_elap}-$_elaP_dec}" \
        "${_elaP_elap:${#_elaP_elap}-_elaP_dec}" \
        "${_elaP_elap2:0:${#_elaP_elap2}-$_elaP_dec}" \
        "${_elaP_elap2:${#_elaP_elap2}-_elaP_dec}"      "${*}"
    $_elaP_setLast2 && _elaP_last2=$_elaP_now
    else
        printf "%6d.%s %s\n" \
        "${_elaP_elap:0:${#_elaP_elap}-$_elaP_dec}" \
        "${_elaP_elap:${#_elaP_elap}-_elaP_dec}"        "${*}"
    fi
    $_elaP_setLast && _elaP_last=$_elaP_now
}

export -f elap
5
27.01.2020, 20:48

Теги

Похожие вопросы