![“set -e -o pipefail” 在 Ubuntu 16 上的 bash 脚本中不起作用](https://linux22.com/image/1059561/%E2%80%9Cset%20-e%20-o%20pipefail%E2%80%9D%20%E5%9C%A8%20Ubuntu%2016%20%E4%B8%8A%E7%9A%84%20bash%20%E8%84%9A%E6%9C%AC%E4%B8%AD%E4%B8%8D%E8%B5%B7%E4%BD%9C%E7%94%A8.png)
我一直在尝试在 Ubuntu 16 上运行我在 CentOS 7 上开发的 bash 脚本。
脚本的第一行是:
set -o nounset -o pipefail -o errexit
当我尝试运行该脚本时,出现以下错误:
project.sh: 6: set: Illegal option -o pipefail
如何解决这个问题?我也在回答这个问题但它没有帮助(我的文件不是make
)。
答案1
在 Ubuntu 上,默认 shell 是dash
(又名 Debian Almquist Shell),它/bin/sh
是符号链接。当您的 shell 脚本使用 运行时#!/bin/sh
,您实际上是在尝试使用默认 shell 运行它。但是,dash
没有选项pipefail
,这就是您收到错误的原因。
# Verifying what /bin/sh is symlinked to dash
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 2月 17 2016 /bin/sh -> dash
# Verify that pipefail doesn't exist as option for dash
$ dash
$ set -o | grep pipefail
$ set -o pipefail
dash: 1: set: Illegal option -o pipefail
$ sh
$ set -o pipefail
sh: 1: set: Illegal option -o pipefail
# Try this same option in bash
$ bash --posix
bash-4.3$ set -o pipefail
bash-4.3$
# no error
答案2
对于那些寻找一个可以绕过dash
Ubuntu 问题的简单脚本的人来说,你可以使用
bash | set +o pipefail
答案3
还有一个可能导致此(或类似)问题的选项:脚本文件中的 Windows 行结尾(CRLF,“\r\n”)。
在 WSL 上发生这种情况的可能性比在原始 Ubuntu 上发生的可能性大得多,但我花了一段时间才发现。
由于行尾错误,解释器将最后一个参数准确读取为pipefail\r
,这被解释为未知参数。但\r
在终端中不可见,这使得很难理解原因。
解决方法是确保文本编辑器中的行尾设置为 LF。
答案4
尝试使用下面的标志,然后它就可以工作了。我已经验证过了。
#!/bin/bash
set -e -o pipefail
# to reset use
# set +e +o pipefail