“export var=value”在哪里不可用?

“export var=value”在哪里不可用?

我发现——可能是在 20 世纪 90 年代中期(!)——这个结构

export var=value

是 Bashism,可移植的表达是

var=value
export var

我多年来一直提倡这一点,但最近有人向我提出质疑,我真的找不到任何文件来支持我曾经坚定的信念。

谷歌搜索"export: command not found"似乎没有提出任何有人确实遇到此问题的案例,所以即使它是真实的,我想这也不是很常见。

(我得到的点击似乎是新手复制/粘贴标点符号,最后得到'export: command not found或类似的,或尝试export与 一起使用sudo;以及csh尝试使用 Bourne shell 语法的新手用户。)

我可以肯定地说它可以在 OS X 和各种 Linux 发行版上运行,sh包括dash.

sh$ export var=value
sh$ echo "$var"
value
sh$ sh -c 'echo "$var"'  # see that it really is exported
value

在当今世界,可以安全地说export var=value使用安全吗?

我想了解一下后果是什么。如果它不能移植到 v7“Bourne classic”,那就只不过是琐事而已。如果在生产系统中 shell 确实无法处理此语法,那么了解这一点将会很有用。

答案1

它不是 bashism,而是符合 POSIX 的语法。它实际上是很久以前作为 kshism 开始的,后来被几乎所有基于 Bourne 语法的 shell 采用。唯一臭名昭著的例外是/bin/shSolaris 10 及更早版本,它坚持旧版 Bourne shell 语法。希望 Solaris 11 使用符合 POSIX 标准的 shell 作为/bin/sh.

顺便说一句,export它已经是旧版 Bourne shell 中的内置命令,因此在谷歌上搜索export: command not found会产生误导。

export以下是与赋值结合使用时的旧版 Bourne shell 行为:

$ export var=22
var=22: is not an identifier

对于怀旧者来说,这个原始Bourne shell的源代码可用并且可以针对大多数 Unix 和 Linux 发行版进行编译。

答案2

export foo=bar

不受 Bourne shell(一种 70 年代的旧 shell,现代实现如 ash/bash/ksh/yash/zsh 均源于此)的支持sh。这是由 引入的ksh

在 Bourne shell 中,您可以执行以下操作:

foo=bar export foo

或者:

foo=bar; export foo

或与set -k

export foo foo=bar

现在,行为:

export foo=bar

因外壳而异。

问题在于赋值和简单命令参数的解析和解释不同。

上面的内容foo=bar被某些 shell 解释为命令参数,而被其他 shell 解释为赋值(有时)。

例如,

a='b c'
export d=$a

被解释为:

'export' 'd=b' 'c'

使用一些 shell(ash,旧版本zsh(在 sh 模拟中),yash)和:

'export' 'd=b c'

在其他 ( bash, ksh) 中。

尽管

export \d=$a

或者

var=d
export $var=$a

在所有 shell 中都会被解释为相同的(如'export' 'd=b' 'c'),因为反斜杠或美元符号会阻止那些支持它的 shell 将这些参数视为赋值。

如果export它本身被引用或者是某些扩展的结果(即使是部分扩展),根据 shell,它也将停止接受特殊处理。

局部变量赋值需要引号吗?了解更多详情。

Bourne 语法如下:

d=$a; export d

所有 shell 的解释都是相同的,没有歧义(d=$a export d也适用于 Bourne shell 和 POSIX 兼容 shell,但不适用于最新版本,zsh除非在sh仿真中)。

情况可能会变得更糟。参见例如最近的讨论bash当涉及到数组的时候。

(IMO,引入这一点是一个错误特征)。

相关内容