相当于 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 语句。

有没有其他方法可以实现它?

谢谢!

【问题讨论】:

为什么不干脆去掉teeif 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。根据mispipemanpage,如果 first 流水线命令失败,mispipe 返回失败的错误代码;如果 any 流水线命令失败,则 bash 中的 -o pipefail 失败。

以上是关于相当于 dash shell 中的 pipefail的主要内容,如果未能解决你的问题,请参考以下文章

如何跳过 ash/dash shell 函数中的第一个参数?

Linux shell语言——dash和bash

了解 dash shell 与 zsh shell

shell: bash和dash

Ubuntu切换默认shell为bash或者dash

ubuntu shell脚本出错 dash