在 bash 函数(而非命令)上使用时间

在 bash 函数(而非命令)上使用时间

如何测量对 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

相关内容