是否有对 shell/Bash 中 stderr 上打印的任何内容的简单测试?

ger*_*ijk 5 bash file-descriptors exit subshell stderr

我想在 shell 脚本中调用一个命令以进行持续集成。退出状态 0 表示成功,否则失败。我正在编写一个包装脚本来运行多个命令,如果其中一个发生任何错误,则失败。

但是,其中一个命令(第 3 方软件)在失败时不符合“事实上的”退出状态 != 1。但是,如果出现故障,它会在 stderr 上打印其错误。

当前的包装器脚本,如果两者都可以正常工作,mycommand并且other-command由于-e切换而失败并退出状态 != 0 :

#!/bin/bash -ex
mycommand --some-argument /some/path/to/file
other-command --other-argument /some/other/file
Run Code Online (Sandbox Code Playgroud)

如何检查打印到 stderr 的任何内容(使主脚本失败)?这是我尝试过的:

  1. stderr 输出重定向到文件,检查文件内容。
    希望避免创建临时文件。
  2. 将 stderr 重定向到 subshel​​l stdin,例如:

    mycommand 2> >(if grep .; then echo NOK; else echo OK; fi)
    
    Run Code Online (Sandbox Code Playgroud)

    这似乎工作正常,但是,我无法控制此处的主 shell 退出,即exit 1不会退出主程序。我也不能控制子外壳之外的变量来传播它的结果。我真的必须创建一个命名管道吗?

  3. 这个答案一样设置额外的文件描述符。
    对我来说看起来不是很优雅,真的。

一些“要求”:

  • 它不应该在 stdout 上的常规输出上失败(也在那里输出)。
  • 我想在标准输出上保留其他有用的输出。
  • 我想保留当前在 stderr 上的任何输出打印(可能是 stdout,但不应该被隐藏)。

所以它应该表现得像一个包装器,只以不干净的状态退出,保留打印输出。

我只是希望有更优雅的东西来检查 stderr 中的任何内容。抨击是可以接受的。

Dop*_*oti 0

# output "NOK" if standard error has any output; "OK" otherwise:
errlog=$(mktemp)
somecommand 1>> "$stdlog" 2> "$errlog"
if [[ -s "$errlog" ]]; then
    # File exists and has a size greater than zero
    echo "NOK"
else
    echo "OK"  
fi
# Done parsing standard error; tack it to the regular log
cat "$errlog" >> "$stdlog"
rm -f "$errlog"
Run Code Online (Sandbox Code Playgroud)