如何检查 ash shell 中管道命令的返回状态?

如何检查 ash shell 中管道命令的返回状态?

如何检查 ash shell 中相互传输的进程的返回代码?

这是我感兴趣的命令:

dd if=/my/block/device | ssh myuser@otherserver "gzip > file.gz" 

另外,我知道这个问题已经针对 bash shell 进行了解答(即使用 PIPESTATUS 数组),但是我的环境使用的是 ash shell。

答案1

我完全不知道ash。这常规解决方法即使在以下情况下也应该有效sh

psf=/tmp/pipestatus
: > "$psf"   # to make the file empty
( dd if=/my/block/device; echo "1 $?" >> "$psf" ) \
| ( ssh myuser@otherserver "gzip > file.gz"; echo "2 $?" >> "$psf" )

然后检查 的内容/tmp/pipestatus。有一个缺陷:竞争条件,两个( )块并行运行,它们可能以不正确的顺序输出到文件。我使用了,>>所以两条消息都不会覆盖另一条消息;“消息”很短,所以它们不应该交错;我给“消息”编号了,所以即使它们没有按顺序排列,你也可以稍后检索正确的顺序(sortcut)。

无论如何,上述代码只是一个例子。更强大的解决方案是mktemp创建临时文件,printf而不是echo。要完全摆脱竞争条件,您需要写入分离文件:

psd="$(mktemp -d)"
# you may want to check if the above command succeeded

( dd if=/my/block/device; printf '%s\n' "$?" > "$psd/f1" ) \
| ( ssh myuser@otherserver "gzip > file.gz"; printf '%s\n' "$?" > "$psd/f2" )

# retrieve the results here, they are in "$psd/f1" and "$psd/f2"

rm -rf "$psd"
unset psd

它不如 Bash 好,PIPESTATUS因为它依赖于文件系统和写入能力,很少出错,而且可能无法被捕获。但总比没有好。

相关内容