awk -F: ' NF!=7 {print}' /etc/passwd
должен сделать это. Если количество полей не 7, то распечатайте его.
Просто используйте time
когда Вы называете сценарий:
time yourscript.sh
Просто звоните times
без аргументов после выхода из Вашего сценария.
С ksh
или zsh
, можно также использовать time
вместо этого. С zsh
, time
также даст Вам, стена показывает время в дополнение к системному процессорному времени и пользователю.
Для сохранения статуса выхода сценария можно сделать его:
ret=$?; times; exit "$ret"
Или можно также включить прерывание EXIT
:
trap times EXIT
Тем путем времена назовут каждый раз, когда выходы оболочки и статус выхода будут сохранены.
$ bash -c 'trap times EXIT; : {1..1000000}'
0m0.932s 0m0.028s
0m0.000s 0m0.000s
$ zsh -c 'trap time EXIT; : {1..1000000}'
shell 0.67s user 0.01s system 100% cpu 0.677 total
children 0.00s user 0.00s system 0% cpu 0.677 total
Также обратите внимание что весь из bash
, ksh
и zsh
имейте a $SECONDS
специальная переменная, которая автоматически увеличивается каждую секунду. В обоих zsh
и ksh93
, та переменная может также быть высказана плавающее мнение (с typeset -F SECONDS
) получить больше точности. Это - только стена, показывают время, не процессорное время.
time
подход представлен ранее. - Я думаю timeit
подход, представленный в коде MATLAB, может быть полезным здесь.
– Léo Léopold Hertz 준영
25.12.2016, 11:37
times
не дает стенное время, правильно? например, bash -c 'trap times EXIT;sleep 2'
– user15964
13.06.2017, 05:17
Если time
не опция,
start=`date +%s`
stuff
end=`date +%s`
runtime=$((end-start))
date
дважды, например, таким образом, Вы могли бы в лучшем случае получить точность миллисекунды на практике, и вероятно меньше), попытайтесь использовать date +%s.%N
. (%N
наносекунды с целой секунды.)
– a CVn
19.10.2012, 22:17
date +%s%N
, или используйте что-то более способное как bc
вычислить фактическое время выполнения от двух значений как jwchew предлагает. Однако, я чувствую, что этот подход является субоптимальным способом сделать его; time
значительно лучше при наличии, по причинам, обрисованным в общих чертах выше.
– a CVn
23.01.2014, 15:29
bc
и затем сделайте это: runtime=$( echo "$end - $start" | bc -l )
– redolent
12.02.2015, 00:01
echo "Duration: $((($(date +%s)-$start)/60)) minutes
– rubo77
29.07.2016, 07:42
Я немного опаздываю к побеждающей стороне, но требуемый для регистрации моего решения (для подвторой точности) в случае, если другие, оказывается, натыкаются на этот поток посредством поиска. Вывод находится в формате дней, часов, минут и наконец секунд:
res1=$(date +%s.%N)
# do stuff in here
res2=$(date +%s.%N)
dt=$(echo "$res2 - $res1" | bc)
dd=$(echo "$dt/86400" | bc)
dt2=$(echo "$dt-86400*$dd" | bc)
dh=$(echo "$dt2/3600" | bc)
dt3=$(echo "$dt2-3600*$dh" | bc)
dm=$(echo "$dt3/60" | bc)
ds=$(echo "$dt3-60*$dm" | bc)
printf "Total runtime: %d:%02d:%02d:%02.4f\n" $dd $dh $dm $ds
Надеюсь, что кто-то там находит это полезным!
date
не поддерживает подвторую точность и просто добавит литерал “N
” к метке времени. А-ч
– Anton Samsonov
12.07.2016, 12:25
dt2=$(echo "$dt%86400" | bc)
. Просто высказывание... BTW я предпочитаю форму dt2=$(bc <<< "${dt}%86400")
но это является совершенно персональным.
– Dani_l
07.03.2018, 18:06
#!/bin/bash
start=$(date +%s.%N)
# HERE BE CODE
end=$(date +%s.%N)
runtime=$(python -c "print(${end} - ${start})")
echo "Runtime was $runtime"
Да, это называется Python, но если вы можете жить с этим, то это довольно милое, лаконичное решение.
] Вот вариант ответа Алекса. Меня волнуют только минуты и секунды, но я также хотел, чтобы он был отформатирован по-другому. Так что я сделал это:[
] [start=$(date +%s)
end=$(date +%s)
runtime=$(python -c "print '%u:%02u' % ((${end} - ${start})/60, (${end} - ${start})%60)")
] #!/bin/bash
begin=$(date +"%s")
Script
termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
#!/bin/csh
#PBS -q glean
#PBS -l nodes=1:ppn=1
#PBS -l walltime=10:00:00
#PBS -o a.log
#PBS -e a.err
#PBS -V
#PBS -M shihcheng.guo@gmail.com
#PBS -m abe
#PBS -A k4zhang-group
START=$(date +%s)
for i in {1..1000000}
do
echo 1
done
END=$(date +%s)
DIFF=$(echo "$END - $START" | bc)
echo "It takes DIFF=$DIFF seconds to complete this task..."
Мой метод для bash
:
# Reset BASH time counter
SECONDS=0
#
# do stuff
#
ELAPSED="Elapsed: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec"
Небольшая функция оболочки, которую можно добавить перед командами для измерения их времени:
tm() {
local start=$(date +%s)
$@
local exit_code=$?
echo >&2 "took ~$(($(date +%s)-${start})) seconds. exited with ${exit_code}"
return $exit_code
}
Затем используйте ее в своем сценарии или в командной строке, например:
tm the_original_command with all its parameters
Используя только bash, также можно измерять и вычислять продолжительность времени для части сценария оболочки (или прошедшее время для всего сценария):
start=$SECONDS
... # do time consuming stuff
end=$SECONDS
теперь вы можете просто распечатать разницу:
echo "duration: $((end-start)) seconds."
если вам нужна только дополнительная продолжительность, выполните:
echo "duration: $((SECONDS-start)) seconds elapsed.."
Вы также можете сохранить продолжительность в переменной:
let diff=end-start
Функция синхронизации основана на SECONDS
, ограничена только вторым -уровнем детализации, не использует никаких внешних команд:
time_it() {
local start=$SECONDS ts ec
printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
printf '%s\n' "$ts Starting $*"
"$@"; ec=$?
printf -v ts '%(%Y-%m-%d_%H:%M:%S)T' -1
printf '%s\n' "$ts Finished $*; elapsed = $((SECONDS-start)) seconds"
# make sure to return the exit code of the command so that the caller can use it
return "$ec"
}
Например:
time_it sleep 5
дает
2019-03-30_17:24:37 Starting sleep 5 2019-03-30_17:24:42 Finished
sleep 5; elapsed = 5 seconds
Просто используйтеtime [any command]
. Пример:time sleep 1
будет спать в режиме реального времени (, т.е. :по секундомеру )из ~от 1,000 до ~1,020 с, как показано здесь:
$ time sleep 1
real 0m1.011s
user 0m0.004s
sys 0m0.000s
Какая красота. Вы можете поместить любую команду после нее, и она выведет результат в удобном для человека -читаемом виде. Мне очень нравится использовать его для временных сборок. Экс:
# time your "make" build
time make
# time your "Bazel" build
time bazel build //path/to/some:target
...или для операций git, которые потенциально могут быть очень длинными,так что я могу развить реалистичные ментальные ожидания:
# time how long it takes to pull from a massive repo when
# I'm working from home during COVID-19. NB: `git pull`
# is sooooo much slower than just pulling the one branch
# you need with `git pull origin <branch>`, so just fetch
# or pull what you need!
time git pull origin master
Для более -настраиваемых временных требований , когда вам может потребоваться манипулировать выводом или преобразовывать его в другие формы, в bash используйте внутреннюю $SECONDS
переменную. Вот демонстрация, включающая преобразование этих секунд в другие единицы, такие как минуты с плавающей запятой:
Обратите внимание, что dt_min
округляется от0.01666666666...
(1 секунда = столько минут )до 0.017
в данном случае, так как я использую для округления функцию printf
. В приведенной ниже части sleep 1;
вы бы вызвали свой скрипт для запуска и времени, но вместо этого я просто сплю в течение 1 секунды ради этой демонстрации.
Команда:
start=$SECONDS; sleep 1; end=$SECONDS; dt_sec=$(( end - start )); \
dt_min=$(printf %.3f $(echo "$dt_sec/60" | bc -l)); \
echo "dt_sec = $dt_sec; dt_min = $dt_min"
Выход:
dt_sec = 1; dt_min = 0.017
bc
и printf
читайте в моем ответе здесь:https://stackoverflow.com/questions/12722095/how-do-i-use-floating-point-division-in-bash/58479867#58479867time
, но, возможно, это было из ответа @ Trudbert прямо здесь . Лично я предпочитаю заключать весь код своего скрипта в какую-нибудь «главную» функцию, например:
main () {
echo running...
}
# stuff...
# calling the function at the very end of the script
time main
Обратите внимание, как легко использовать команду time
в этом сценарии. Очевидно, вы не измеряете точное время, включая время анализа скрипта, но я считаю его достаточно точным в большинстве ситуаций.
Использовать встроенное время bash?
time: time [-p] PIPELINE
Execute PIPELINE and print a summary of the real time, user CPU time,
and system CPU time spent executing PIPELINE when it terminates.
The return status is the return status of PIPELINE. The `-p' option
prints the timing summary in a slightly different format. This uses
the value of the TIMEFORMAT variable as the output format.
Пример:
TIMEFORMAT="The command took %Rs"
time {
sleep 0.1
}
Выход:
The command took 0.108s
Принятое решение с использованием time
записывается в stderr
.
Решение с использованием times
записывается в stdout
.
В решениях, использующих $SECONDS
, отсутствует точность менее -секунды.
Другие решения включают вызов внешних программ, таких как date
или perf
, что неэффективно.
Если у вас все в порядке с любым из них, используйте его.
Но если вам нужно эффективное решение для получения времени с миллисекундной точностью и вам нужно преобразовать его в переменные так, чтобы исходный вывод оставался неизменным вы можете комбинировать подстановку процесса с некоторыми перенаправлениями вокруг time
, что намного быстрее, чем вызов внешних программ, и позволяет перенаправления вокруг сценария-оболочки синхронизации, как в исходной команде/сценарии.
# Preparations:
Cmd=vgs # example of a program to be timed which is writing to stdout and stderr
Cmd="eval { echo stdout; echo stderr >&2; sleep 0.1; }" # other example; replace with your own
TIMEFORMAT="%3R %3U %3S" # make time output easy to parse
Выберите один из следующих вариантов разбора вывода time
в соответствии с вашими потребностями:
Кратчайший вариант, где stdout
из $Cmd
записывается в stderr
и ничего вstdout
:
read Elapsed User System < <({ time $Cmd 2>&3; } 3>&2 2>&1 >&3)
Более длинный вариант, в котором оригинал stdout
и stderr
отделены друг от друга:
{ read Elapsed User System < <({ time $Cmd 2>&4; } 4>&2 2>&1 >&3); } 3>&1
Самый сложный вариант включает в себя закрытие дополнительных файловых дескрипторов, так что $Cmd
вызывается как бы без этой временной оболочки вокруг него, а lvm
такие команды, как vgs
, не жалуются на утечку файловых дескрипторов:
{ read Elapsed User System < <({ time $Cmd 2>&4 4>&-; } 4>&2 2>&1 >&3 3>&-); } 3>&1
Вы даже можете имитировать сложение с плавающей запятой в bash
без вызова bc
, что было бы намного медленнее:
CPU=`printf %04d $((10#${User/.}+10#${System/.}))` # replace with your own postprocessing
echo CPU ${CPU::-3}.${CPU: -3} s, Elapsed $Elapsed s >&2 # redirected independent of $Cmd
Возможные результаты двух примеров $Cmd
при медленном ЦП:
File descriptor 3 (/dev/pts/1) leaked on vgs invocation. Parent PID 10756: bash
File descriptor 4 (/dev/pts/1) leaked on vgs invocation. Parent PID 10756: bash
VG #PV #LV #SN Attr VSize VFree
b3 3 24 0 wz--n- 1.31t 1.19t
CPU 0.052 s, Elapsed 0.056 s
Или:
stdout
stderr
CPU 0.008 s, Elapsed 0.109 s
аналогично ответу @LeZuse, но поддерживает аргументы скрипта:
#!/bin/bash
main () {
echo "my first argument is $1"
# script content here
}
# "$@" will expand to the script's arguments
time main "$@"
real
,user
иsys
. Для значений их посмотрите здесь. – Garrett 09.07.2015, 04:56time $( ... ) >> out.txt
– Jon 25.04.2018, 21:18time (command1 && command2)
– meetar 25.04.2018, 23:30