相当于 dash shell 中的 pipefail
Posted
技术标签:
【中文标题】相当于 dash shell 中的 pipefail【英文标题】:equivalent of pipefail in dash shell 【发布时间】:2013-07-19 09:15:07 【问题描述】:dash
shell 中是否有一些类似的选项对应于bash
中的pipefail
?
如果管道中的命令之一失败(但不会像set -e
那样退出),或者任何其他获取非零状态的方式。
为了更清楚,这是我想要实现的示例:
在一个示例调试 makefile 中,我的规则如下所示:
set -o pipefail; gcc -Wall $$f.c -o $$f 2>&1 | tee err; if [ $$? -ne 0 ]; then vim -o $$f.c err; ./$$f; fi;
基本上它运行时会打开错误文件和源文件,并在没有错误时运行程序。节省了我一些打字时间。以上 sn-p 在 bash
上运行良好,但我较新的 Ubunty 系统使用 dash
,它似乎不支持 pipefail
选项。
如果以下命令组的第一部分失败,我基本上想要一个 FAILURE 状态:
gcc -Wall $$f.c -o $$f 2>&1 | tee err
这样我就可以将它用于if
语句。
有没有其他方法可以实现它?
谢谢!
【问题讨论】:
为什么不干脆去掉tee
? if gcc -Wall $$f.c -o $$f >$$f.log 2>&1; then cat $$f.log; ./$$f; else vim -o $$f.c $$f.log; fi
(或者,在 Ubunty 上安装 bash
。这只是一个简单的方法。)
@rici 谢谢!我使用 tee 是因为我还希望将 stderr 输出打印到屏幕上——主要是为了查看是否有任何警告。但是,如果没有其他方法,我可能会切换到您的建议。关于安装 bash:我曾假设(没有任何研究)dash 是从 bash 向前迈出的一步,所以我不想切换回去,但现在谷歌搜索了一下似乎不一定如此。我将阅读更多有关差异的信息,然后再决定。再次感谢您的指点!
PIPESTATUS / pipefail 的 POSIX 实现的“库存”答案在 comp.unix.shell FAQ Q11
我希望上面提到的 set -e 可以为我提供一个相当于 set -o pipefail 的破折号,但不是这样:$ dash -c 'set -e; false | cat'; echo $? 0 $
【参考方案1】:
我遇到了同样的问题,set -o pipefail
和 $PIPESTATUS[0]
的 bash 选项在我正在使用的 docker 映像的 dash shell (/bin/sh) 中都失败了。我宁愿不修改图像或安装另一个包,但好消息是使用命名管道对我来说非常有效 =)
mkfifo named_pipe
tee err < named_pipe &
gcc -Wall $$f.c -o $$f > named_pipe 2>&1
echo $?
查看我在哪里找到信息的答案:https://***.com/a/1221844/431296
【讨论】:
【参考方案2】:Q 的示例问题需要:
如果 ... 命令组的 第一部分 失败,我基本上想要一个 FAILURE 状态:
安装moreutils,并尝试mispipe
util,它返回管道中first命令的退出状态:
sudo apt install moreutils
然后:
if mispipe "gcc -Wall $$f.c -o $$f 2>&1" "tee err" ; then \
./$$f
else
vim -o $$f.c err
fi
虽然 'mispipe' 在这里完成了这项工作,但它并不是 bash
shell 的 pipefail
的完全相同的副本;来自man mispipe
:
Note that some shells, notably bash, do offer a
pipefail option, however, that option does not
behave the same since it makes a failure of any
command in the pipeline be returned, not just the
exit status of the first.
【讨论】:
值得注意的是,这将处理问题中的特定情况,但仍不等同于-o pipefail
。根据mispipe
manpage,如果 first 流水线命令失败,mispipe 返回失败的错误代码;如果 any 流水线命令失败,则 bash 中的 -o pipefail
失败。以上是关于相当于 dash shell 中的 pipefail的主要内容,如果未能解决你的问题,请参考以下文章