如何将 PIPESTATUS、tee 和 /bin/sh 一起使用?

如何将 PIPESTATUS、tee 和 /bin/sh 一起使用?

当我跑步时

curl | tee test.txt; echo ${PIPESTATUS[0]}

我正确地看到

curl:尝试“curl --help”或“curl --manual”获取更多信息

2

但是当我尝试使用 '/bin/sh' 运行完全相同的命令时:

sh -c "curl | tee test.txt; echo \${PIPESTATUS[0]}"

我明白了

curl:尝试“curl --help”或“curl --manual”获取更多信息

sh: 1:错误替换

Bad substitution请问我们如何解决这个问题?

答案1

您可以通过不使用 来解决此问题sh

具体来说PIPESTATUS${var[idx]} 大批语法是 Bash shell 特有的功能。POSIX 中不存在这些功能甚至还有数组可能使用不同的语法。

有些 Linux 发行版会将其符号链接/bin/sh到 Bash。而其他发行版则会将其符号链接到短跑、Debian Almquist Shell。两者都与 POSIX 兼容脚本,但只有 Bash 接受该${PIPESTATUS[…]}语法。

因此如果您想使用它,请运行bash -c "…"

答案2

'/bin/sh' 或 busybox 的解决方法

status=0
eval ` { ls /dontexists || echo status="$?"; } | tee /dev/null`
echo "# status=${status}"

痕迹 :

busybox sh ~/bin/test.sh 
+ status=0
+ ls /dontexists
+ tee /dev/null
ls: /dontexists: No such file or directory
+ echo status=1
+ eval status=1
+ status=1
+ echo # status=1
# status=1

答案3

另外,从 tcsh 调用 'bash -c' 时似乎有问题:

bash -c "curl | tee test.txt; echo \${PIPESTATUS[0]}"

PIPESTATUS:未定义变量。

这对我来说在 tcsh 中是有效的:

bash -c 'curl | tee test.txt; echo ${PIPESTATUS[0]}'

curl:尝试“curl --help”或“curl --manual”获取更多信息
2

GNU bash,版本 4.2.25(1)-release (x86_64-pc-linux-gnu)
从 tcsh 6.17.06 调用

答案4

您可能会问这个问题,因为您使用的 busybox shell 没有数组PIPESTATUS。在这种情况下,唯一的选择就是。但是,如果您使用的是没有或 的set -o pipefail几乎已绝迹的 shell 之一,那么您可以考虑为中间输出或返回值编写临时文件。PIPESTATUS-o pipefail

相关内容