如何检查 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
。有一个缺陷:竞争条件,两个( )
块并行运行,它们可能以不正确的顺序输出到文件。我使用了,>>
所以两条消息都不会覆盖另一条消息;“消息”很短,所以它们不应该交错;我给“消息”编号了,所以即使它们没有按顺序排列,你也可以稍后检索正确的顺序(sort
,cut
)。
无论如何,上述代码只是一个例子。更强大的解决方案是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
因为它依赖于文件系统和写入能力,很少出错,而且可能无法被捕获。但总比没有好。