我在这里找到了一些关于“if”语句之间[
和[[
“if”语句之间差异的非常好的答案。对于特定的命名 shell,使用[[
over似乎是个好主意[
(而且速度也更快)。
然而,我仍然不清楚可移植性。如果我的目标是为 POSIX 兼容 shell 编写一个脚本,我将以 开头的脚本#!/bin/sh
,这种语法是多么允许。据我所知,双括号不在 POSIX 标准中,但在“现实世界”中这到底有多大问题?
我想我的意思是我想要一个可移植的脚本,但它足以在所有可行的 POSIX shell 上运行,比如 2000-2005 年。这意味着,它不是标准的一部分,这是事实,但实际上从 2005 年开始,任何 shell 几乎肯定会接受该语法。
另外,还有一个关于脚本可移植性和 POSIX 的更普遍的问题:其他作者如何处理这个问题?我理解用例和目标受众决定了大部分决策,但是您是否尝试尽可能接近 POSIX 以减少整个互联网可能出现的不兼容性,或者您是否利用大多数 shell 的所有好东西尚未达到 POSIX 标准的支持?
我首先尝试使我的大部分脚本尽可能兼容 Bourne 和 POSIX。不过,随着时间的推移,通过阅读更多的 Bash 文档以及在网上查看其他人的脚本,我不得不说,利用这些其他功能可以使脚本更易于阅读,并且在许多情况下更小。
答案1
如果我的目标是为 POSIX 兼容的 shell 编写一个脚本,我将以 #!/bin/sh 开头的脚本,这种
[[
语法是多么允许。
一点也不。许多现代基于 Linux 的系统都使用dash
默认情况下/bin/sh
,这是完全符合 POSIX 标准没有更多了,所以[[
不会起作用。这包括最近的每一个德班和乌班图发行版及其衍生品,以及许多其他发行版。从历史上看,这些系统通常使用 Bash 来代替,并有意切换以提高性能。
许多其他系统,包括大多数 BSD 和大多数商业 Unices,都不支持,[[
也从来不支持:它们sh
仅支持 POSIX,或者其扩展不包含语法[[
。开放BSD确实sh
支持 的一个版本[[
,该版本与 Bash 的略有不同;我不知道还有其他人这样做,尽管它们可能存在。否则,只有使用 Bash 的系统/bin/sh
(或较少使用zsh
,甚至较少使用其他系统)才能[[
在声明为sh
脚本的内容中工作。
另一方面,在实践中,绝大多数系统都安装了 Bash,只需明确运行脚本bash
就足以满足所有系统的需要。无论如何, Bash 的sh
模拟模式总是被破坏。
由于您依赖于 Bash 功能,因此我完全看不出您想要将其声明为脚本的任何理由sh
:只需说出#!/bin/bash
并完成,使用[[
随心所欲——甚至更好,完全排除[
.如果您想要最大的便携性,请使用[
或者test
和 POSIX sh
1,并仔细书写。
1请注意,一些商业 Unices 具有或曾经具有非 POSIXsh
作为/bin/sh
;为了统一工作,您需要使用系统 POSIX 的完整路径运行脚本sh
。