【问题标题】:How to Calculate Execution Time and Get Command Exit Code如何计算执行时间并获取命令退出代码
【发布时间】:2022-02-16 17:54:17
【问题描述】:

我编写了一个 shell 脚本,我想获得一个命令的执行时间,但我也将命令的输出重定向到一个文件。另外,我需要获取此特定命令的退出代码才能在 if 语句中使用它。这是我尝试过的:

...
TIMEFORMAT=%R

log_file() {
  echo "$PROJECT_DIR/logs/$1_$(date +%Y%m%d_%H%M%S).log"
}    

CODE_TIME=$(time sh -c "ipython -c "%run ./foo.ipynb" > $(log_file "log_file_name") 2>&1")

CODE_RESULT=$?

echo "Code_Result: $CODE_RESULT"

if [ "$CODE_RESULT" -eq 0 ]

    ...

根据time 的文档,它返回命令的退出代码,但我也在函数中执行echo 命令。那么,任何人都知道如何获得ipython 命令的退出代码?谢谢。

【问题讨论】:

  • 您在计时中寻找什么样的精度......最近的分钟?最近的秒?最接近的毫秒?如果“最近的第二个”就足够了,那么考虑访问 bash 的 $SECONDS 变量,简单的比如:start=$SECONDS; run-command; CODE_RESULT=$?; end=$SECONDS; duration=$((end-start))
  • SECONDS=0; run-command; CODE_RESULT=$?; echo $SECONDS
  • @markp-fuso @Cyrus 我想在几秒钟内得到,但我正在使用 ShellCheck,它会警告我 $SECONDS 变量。所以,我搜索了一个替代方案,TIMEFORMAT=%R 为我工作以获得秒数。

标签: linux bash shell time sh


【解决方案1】:

您在示例调用中的引用不寻常。我会期待的

sh -c "ipython -c "%run ./foo.ipynb" > $(log_file "log_file_name") 2>&1"

被翻译成

sh -c 'ipython -c %run' './foo.ipynb > somewhere/logs/log_file_name_somedate.log 2>&1'

至于time wrt 返回码的行为,我的bash (5.1.16) 的行为是这样的:

$ time ls "I do not exist" > $(echo newfile) 2>&1

real    0m0,004s
user    0m0,004s
sys     0m0,000s

$ echo $?
2

$ cat newfile
"I do not exist": No such file or directory (os error 2)

还有这样的重定向:

$ capture="$(time (ls "I do not exist" > $(echo newfile2) 2>&1) 2>&1)"

$ echo $?
2

$ echo "$capture"

real    0m0,004s
user    0m0,004s
sys     0m0,000s

$ cat newfile2
"I do not exist": No such file or directory (os error 2)

因此,我建议您尝试将呼叫更改为:

CODE_TIME="$(time (sh -c "ipython -c '%run ./foo.ipynb' > $(log_file "log_file_name") 2>&1") 2>&1)"

CODE_RESULT=$?

【讨论】:

  • 抱歉,我忘了在脚本中添加TIMEFORMAT=%R。所以,它只打印真实的部分。我会尝试写出结果。谢谢你的帮助。
  • 非常感谢。有效。你有关于何时使用" ... "' ... '$( ... )${ ... } 等的文档吗?我对这些的用法有点困惑。另外,您能否解释一下为什么使用第二个2>&1 部分?谢谢。
  • @AHOME 这是一个非常广泛的问题。前两个是String Literals,区别在于" 可以进行扩展(见下文)。第三个称为Command Substitution,它允许您捕获和处理子shell 的输出。最后一个,Shell Parameter Expansion,本质上是访问变量的方式。
  • @AHOME2>&1的用途。在这里,两者都将stderr 重定向到stdout。在第一个或内部情况下,它用于捕获内部命令的输出(ls 及其在我的示例中的错误消息),而第二个或外部捕获您想要的 time 命令的输出存储在一个变量中(与我只使用一次的情况相比:内部输出被捕获,而time 的输出被打印)。
猜你喜欢
  • 2016-10-10
  • 2018-03-29
  • 1970-01-01
  • 2014-06-14
  • 2018-11-04
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
相关资源
最近更新 更多