我想在我的脚本中使用严格模式。我也很欣赏便携性。
设置-o管道故障似乎是强制性的。然而shellcheck
(静态 linter)对“在 POSIX sh 中,设置选项 pipelinefail 未定义”感到不满。
这是对的吗?如果是这样,这只是一个bash
功能还是相当丰富?
答案1
该pipefail
选项来自 ksh93,也存在于其他一些 shell 中。添加了:
- 至 ksh93g1998年发布
- 猛击2004年发布3.0
- 2009年到busybox ash
- 2010年到busybox安静
- 致 mkshr46于2013年发布
- 到 zsh2013年发布5.0.3
- 到 yash 2.422016年发布
- 2017 年转至 NetBSD sh
- 2019 年转至 FreeBSD sh
- 2020 年升级至 OpenBSD sh
A请求将其添加到 POSIX 标准于 2013 年提交,并于 2019 年接受决议。因此,它将属于该标准的下一次重大修订。
其余实现(主要是 dash、bosh 和基于 ksh88 的 shell)可能仍需要更多时间来添加对其的支持。之后,“EOL”时钟将开始计时,10 年后您将能够假设当前支持的系统上的所有 sh 实现都将支持它。
答案2
shellpipefail
选项特定于许多声称shellcheck
支持1 的shell 。如果通过“可移植性”您假设任何目标系统都有支持它的 shell(以及您可能使用的任何其他构造),则您可以使用此 shell 选项并实现可移植。这与任何其他特定脚本语言所获得的“可移植性”类型相同。
如果 linter在 shell 脚本中shellcheck
发现一个脚本,它会抱怨,因为 POSIX 目前不支持它。set -o pipefail
sh
sh
bash
为了确保您的脚本是由shell(或您正在为其编码的任何特定 shell)解释的脚本,该脚本应该有一个#!
-line 指向正确的 shell 解释器,例如,
#!/bin/bash
或者可能
#!/usr/bin/env bash
或类似的东西。
使用正确的#!
- 行另外指示脚本将由不是 的特定 shell 解释sh
,shellcheck
linter 不会抱怨您pipefail
在脚本中设置 shell 选项。
如果您不在#!
脚本中使用 -line,那么您应该考虑这样做(或者始终在命令行上使用显式解释器运行脚本)。同时,可以使用其(或) 选项shellcheck
告诉命令行工具切换到模式:-s
--shell=
shellcheck --shell=bash myscript
1我怀疑shellcheck
有一个“POSIXsh
模式”和一个“其他模式”来支持bash
、、dash
和ksh
(shellcheck
不声称支持zsh
)。 shellpipefail
选项被记录为可与bash
, 和 一起使用ksh
。 shellzsh
有一个PIPE_FAIL
shell 选项,可以用同样的方式设置。 shelldash
不支持该选项,但如果#!
-line 提到dash
,shellcheck
则不会抱怨pipefail
。
答案3
当脚本在不支持的 shell 上运行时,您希望发生什么pipefail
?
结果顺序很重要一些但贝壳并不是故事的全部。即使在单个命令中,bash 也关心顺序set
- 它继续set -o NoSuchOption -e
VS 退出set -e -o NoSuchOption
。