如何在bash脚本中存储“time”函数输出的子string

所以bash的内置时间函数应该以这种格式输出

real 0m0.002s user 0m0.001s sys 0m0.000s 

我想要以毫秒为单位保存用户的时间,如001这是干净的方式吗?

Solutions Collecting From Web of "如何在bash脚本中存储“time”函数输出的子string"

干净的方法是使用TIMEFORMAT shell变量来只打印用户信息。 ( man bash的更多细节。)

那么,当然你需要捕获它的输出。 这是不可能的,因为它是由shell在内部完成的,但是你可以在子shell中运行它,并且输出将会变成标准错误。 但是你必须以某种方式将命令的输出重定向到其他地方。 在这里,我只是抛弃它,但是还有很多其他的可能性,具体取决于你需要做什么。 那么你需要将d.ddd转换成dddd 。 只是删除期限将这样做。

 (TIMEFORMAT="%U"; time ls > /dev/null) |& tr -d . 

如果你喜欢,你可以添加| sed s/^0*// | sed s/^0*//消除前导零。

%R将给出实时,%S的系统时间。 你可以用例如%6U来改变精度来得到微秒,虽然大多数系统不会接近精确的。

man bash帮助重定向。 man trman sed帮助如何使用它们。

Bash的内置time有点棘手,因为它具有特殊的处理能力,所以它可以返回整个流水线的处理时间,比如time ls -l | sort | uniq time ls -l | sort | uniq time ls -l | sort | uniq而不仅仅是在我的例子中只有ls -l命令的处理时间。

捕获时间输出的最好方法是以下重定向技术:

 exec 3>&1 4>&2 foo=$( { time some_command 1>&3 2>&4; } 2>&1 ) # change some_command exec 3>&- 4>&- 

在这一点上,如果你要echo "$foo"你会看到按顺序的东西

 real 0m0.013s user 0m0.004s sys 0m0.007s 

现在要得到004部分,你有很多选择:sed,awk或者直接bash来命名前三名。我个人最喜欢的是awk,它看起来像这样:

 foo=$({ time some_command 1>&3 2>&4;} 2>&1 | awk -F'[s.]' '/user/{print $3}') 

现在,如果你要echo "$foo"你会看到只是004

使用bash的内置字符串globbing你可以做这样的事情:

 output="real 0m0.002s user 0m0.001s sys 0m0.000s" #get everything to the right of first "*user " user=${output#*user } #get everything to the left of the first "s*" user=${user%%s*} #get everythig to let left of "m*" min=${user%%m*} #get everything to the right of "*m" and left of ".*" sec=${user#*m} sec=${sec%%.*} #get everything to the right of "*." usec=${user#*.} time=$[$usec + $sec * 1000 + $min * 60000] 

结果运行bash -x

 + output='real 0m0.002s user 0m0.001s sys 0m0.000s' + user='0m0.001s sys 0m0.000s' + user=0m0.001 + min=0 + sec=0.001 + sec=0 + usec=001 + time=1