![如何将 PIPESTATUS、tee 和 /bin/sh 一起使用?](https://linux22.com/image/1394523/%E5%A6%82%E4%BD%95%E5%B0%86%20PIPESTATUS%E3%80%81tee%20%E5%92%8C%20%2Fbin%2Fsh%20%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%EF%BC%9F.png)
当我跑步时
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