我正在尝试在 Bash 脚本中执行以下操作,想知道是否可行:
- 使用以下命令计算命令(本例中为 mysql)的输出时间
time
- 抑制命令的标准输出
- 发生错误时捕获命令的 stderr 输出
- 运行命令后检查其退出状态码
这是一个复杂的链,我没能将它们全部整合在一起。如果我停止使用时间,我可以让状态代码正常工作。
这是我目前所拥有的:
# the setup
TIMEFORMAT=%R
MYSQL=mysql <options>
# execute and time a query (does more than is listed here)
function executeQuery {
TIME=$( time ( $MYSQL "$1" 2>&1 | tee /tmp/somefile.txt > /dev/null ) 2>&1 )
# do something with $?
}
我使用 tee 将命令中的任何错误响应重定向到文件,然后将生成的 stdout 发送到 /dev/null。然后我将 time 命令的 stderr 重定向到 stdout,最终结果应为 $TIME。
现在,如果我将该行更改为如下内容:
TIME=$( time ( $MYSQL "$1" 2>&1 | tee /tmp/somefile.txt > /dev/null; exit ${PIPESTATUS[0]} ) 2>&1 )
它正确地从 mysql 发回退出代码,但破坏了时间命令。
这真的可能吗?我是不是漏掉了什么?希望目标是明确的。
谢谢!
答案1
bashtime
是个很麻烦的问题。如果没有像多层子 shell 这样的恶意 shell 攻击,它的输出是无法重定向的。 http://mywiki.wooledge.org/BashFAQ/032建议正确答案是:
TIME = $( ( time $MYSQL "$1" 2>&1 | tee /tmp/somefile.txt > /dev/null; exit ${PIPESTATUS[0]} ) 2>&1 )
请注意,bashtime
将整个管道作为参数,因此将子 shell 放在时间调用之后是不正确的。
经过测试
TIME = $( ( time ls /asdfasfdsfs 2>&1 | tee asdf 2>&1 >/dev/null ; exit ${PIPESTATUS[0]} ) 2>&1 );
echo $?;
echo $TIME
这给了我
2
real 0m0.003s user 0m0.004s sys 0m0.004s