如何测量对 bash 函数的单独调用里面bash 文件。
我有一个使用命令调用的程序
eclipse -b col_solve.pl -e "myPred"
这个调用输出一些信息,最后一个是SUCCESS或FAIL。我正在编写一个脚本,该脚本在目录中的一堆文件上调用,并且对于每个文件,输出
- 名字
- 状态(成功或失败)
- 以及执行 所花费的(用户)时间。
这是我知道有效的代码:
我用它来获取状态(检索输出中的最后一个单词):
stat=
get_stat ( ){
stat=$(awk '{print $NF}' <<< $1);
}
我用它来调用程序:
run_eclipse_on ( ){
get_stat "$(eclipse -b col_solve.pl -e "run(\"$1\")" )";
}
有问题的代码如下:
for i in `ls $1` ; #where $1 is the directory containing the files
do
tps=$(/usr/bin/time -f %U \ #to get just the user time
[run_eclipse_on $1/$i] ); # HERE it is!
echo $i::$stat::::$tps; # gives, for ex: file_name::SUCCESS::::0.20
done
罪魁祸首是调用该函数的那一行。我尝试用`、{、[、$(、'和"包围它。没有任何效果......
甚至可能吗...?
答案1
使用time
关键词而不是外部命令。使用关键字允许您运行time
任何 shell 命令,包括函数调用,而不仅仅是运行程序。您可以通过以下方式在某种程度上控制输出格式TIMEFORMAT
多变的。
TIMEFORMAT=%2U
time run_eclipse_on …
echo "$i::$stat"
不过,输出time
会打印在自己的行上。 Bash 允许一个技巧:你可以TIMEFORMAT
在命令期间进行更改,这样你就可以在其中填充更多的东西。
time { run_eclipse_on …; TIMEFORMAT="${i//%/%%}::${stat//%/%%}::%2U"; }
的输出time
被打印到标准错误。如果您需要在标准输出上使用它,只需使用2>&1
.然而,这也将重定向打印在 stderr 上的任何命令。为了保留 stderr,你可以做一些文件描述符改组。
{ time { {
run_eclipse_on …;
TIMEFORMAT=$stat::%2U;
} 2>&3; } 2>&1; } 3>&2
答案2
听起来你想要这样的东西:
#!/bin/bash
for f in "$1"/*; do
time eclipse -b col_solve.pl -e "$f" | tail -n 1
done
不要在 shell 脚本中使用函数,除非您实际上需要他们。使用 shell 脚本的好处是您可以轻松地编排其他工具。让工具而不是 shell 来完成工作。只需使用 shell 将其他工具串起来即可。
进一步阅读:
答案3
虽然与“用户时间”不同,但如果经过的时间就足够了,另一种选择是保存开始和结束时间并计算函数调用中经过的时间。timer
列出的功能这里让这变得更容易。
在这里复制该函数以便于参考:
# Elapsed time. Usage:
#
# t=$(timer)
# ... # do something
# printf 'Elapsed time: %s\n' $(timer $t)
# ===> Elapsed time: 0:01:12
#
#
#####################################################################
# If called with no arguments a new timer is returned.
# If called with arguments the first is used as a timer
# value and the elapsed time is returned in the form HH:MM:SS.
#
function timer()
{
if [[ $# -eq 0 ]]; then
echo $(date '+%s')
else
local stime=$1
etime=$(date '+%s')
if [[ -z "$stime" ]]; then stime=$etime; fi
dt=$((etime - stime))
ds=$((dt % 60))
dm=$(((dt / 60) % 60))
dh=$((dt / 3600))
printf '%d:%02d:%02d' $dh $dm $ds
fi
}
在您的情况下,您将包含此函数,然后:
for i in *
do
t=$(timer)
run_eclipse_on $i
elapsed=$(timer $t)
echo $i::$stat::::$elapsed # gives, for ex: file_name::SUCCESS::::0:00:03
done