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

tri*_*eee 33 shell compatibility history

我已经发现——可能是在 1990 年代中期(!)的 Usenet 上——构造

export var=value
Run Code Online (Sandbox Code Playgroud)

是一种 Bashism,可移植的表达方式是

var=value
export var
Run Code Online (Sandbox Code Playgroud)

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

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

(我得到的点击似乎是复制/粘贴标点符号的新手,结果是'export: command not found或一些这样的,或者尝试使用exportwith sudo; 以及csh尝试使用 Bourne shell 语法的新手用户。)

我可以肯定的告诉大家,它适用于OS X和各种Linux发行版,包括那些地方shdash

sh$ export var=value
sh$ echo "$var"
value
sh$ sh -c 'echo "$var"'  # see that it really is exported
value
Run Code Online (Sandbox Code Playgroud)

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

我想了解后果是什么。如果它不能移植到 v7“Bourne classic”,那也不过是琐事。如果有 shell 真的无法处理这种语法的生产系统,那么知道这会很有用。

jll*_*gre 30

它不是 bashism,而是符合 POSIX 的语法。它实际上在很久以前就作为 kshism 开始使用,后来被几乎所有基于 Bourne 语法的 shell 所采用。唯一臭名昭著的例外是/bin/sh在 Solaris 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
Run Code Online (Sandbox Code Playgroud)

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

  • 那不是原始 Bourne shell 的源代码,而是修改后的 OpenSolaris sh。它是 Bourne 外壳,但经过数十年的演变。Unix V7 附带的原始 Bourne shell 可以在 [Unix Heritage Society](http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh ) (4认同)

Sté*_*las 22

export foo=bar
Run Code Online (Sandbox Code Playgroud)

不受 Bourne shell(一个 70 年代的旧 shell,现代sh实现如 ash/bash/ksh/yash/zsh 派生自)不支持。那是介绍的ksh

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

foo=bar export foo
Run Code Online (Sandbox Code Playgroud)

或者:

foo=bar; export foo
Run Code Online (Sandbox Code Playgroud)

或与set -k

export foo foo=bar
Run Code Online (Sandbox Code Playgroud)

现在,行为:

export foo=bar
Run Code Online (Sandbox Code Playgroud)

因壳而异。

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

foo=bar上述被一些壳作为命令参数和由他人解释为分配(有时)。

例如,

a='b c'
export d=$a
Run Code Online (Sandbox Code Playgroud)

被解释为:

'export' 'd=b' 'c'
Run Code Online (Sandbox Code Playgroud)

使用一些外壳(ash,旧版本zsh(在 sh 仿真中),yash)和:

'export' 'd=b c'
Run Code Online (Sandbox Code Playgroud)

在其他 ( bash, ksh) 中。

尽管

export \d=$a
Run Code Online (Sandbox Code Playgroud)

或者

var=d
export $var=$a
Run Code Online (Sandbox Code Playgroud)

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

如果export本身被引用或某些扩展(甚至部分)的结果,取决于外壳,它也将停止接受特殊处理。

有关更多详细信息,请参阅“局部变量赋值是否需要引号? ”。

Bourne 语法:

d=$a; export d
Run Code Online (Sandbox Code Playgroud)

被所有 shell 解释为相同的,没有歧义(d=$a export d也可以在 Bourne shell 和 POSIX 兼容的 shell 中工作,但不能在最新版本中使用,zsh除非在sh仿真中)。

它可能会变得更糟。例如bash参见最近关于何时涉及数组的讨论

(IMO,引入该功能是错误的)。

  • @jrw32982,因为它是内置的。你仍然可以在现代 POSIX shell 中得到它,但 [仅适用于 _special_ 内置函数](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_14) 是 `export`。 (3认同)