bash脚本:如何在管道中保存第一个命令的返回值?

Geo*_*ung 9 bash pipeline return-value

Bash:我想运行一个命令并通过一些过滤器管道结果,但如果命令失败,我想返回命令的错误值,而不是过滤器的无聊返回值:

例如:

if !(cool_command | output_filter); then handle_the_error; fi
Run Code Online (Sandbox Code Playgroud)

要么:

set -e
cool_command | output_filter
Run Code Online (Sandbox Code Playgroud)

在任何一种情况下,它cool_command都是我关心的返回值- 对于第一种情况中的'if'条件,或者在第二种情况下退出脚本.

这样做有什么干净的习惯用法吗?

Dae*_*yth 15

使用PIPESTATUS内置变量.

来自man bash:

PIPESTATUS

一个数组变量(请参阅下面的数组),其中包含最近执行的前台管道(可能只包含一个命令)中的进程的退出状态值列表.

  • 只是为了完成答案,`[[$ {PIPESTATUS [0]} -ne 0]] && handle_the_error` (2认同)

小智 0

如果您不需要显示命令的错误输出,您可以执行类似的操作

if ! echo | mysql $dbcreds mysql; then
    error "Could not connect to MySQL. Did you forget to add '--db-user=' or '--db-password='?"
    die "Check your credentials or ensure server is running with /etc/init.d/mysqld status"
fi
Run Code Online (Sandbox Code Playgroud)

在示例中,error 和 die 是已定义的函数。脚本中的其他地方。$dbcreds 也被定义,尽管这是从命令行选项构建的。如果该命令没有生成错误,则不会返回任何内容。如果发生错误,该特定命令将返回文本。

如果我错了,请纠正我,但我的印象是你真的想做一些比

[ `id -u` -eq '0' ] || die "Must be run as root!"
Run Code Online (Sandbox Code Playgroud)

您实际上在 if 语句之前获取用户 ID,然后执行测试。通过这种方式,您可以根据需要显示结果。这将是

UID=`id -u`
if [ $UID -eq '0' ]; then
    echo "User is root"
else
    echo "User is not root"
    exit 1 ##set an exit code higher than 0 if you're exiting because of an error
fi
Run Code Online (Sandbox Code Playgroud)