哪里没有“ export var = value”?


31

我可能是在1990年代中期在Usenet上发现的(!)

export var=value

是Bashism,而可移植的表达是

var=value
export var

我一直提倡这一点,但是最近有人挑战了我,我真的找不到任何文档来支持我的坚定信念。

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

(我发现的命中点似乎是新手,他们复制/粘贴了标点符号,并最终使用了'export: command not found或类似的东西,或者试图exportsudo; 一起使用;而新手csh用户则尝试使用Bourne shell语法。)

我可以肯定地说它可以在OS X以及各种Linux发行版上运行,包括shis 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确实无法使用此语法,那么了解这一点将很有用。


2
谢谢,我终于明白为什么我经常看到我认为没用的东西:var = value; export var
Thorsten Staerk 2015年

2
仍然有一些Solaris盒子在起作用,而众所周知,这些盒子在其标准工具中非常节俭。在频谱的另一端,它不busybox具有自己的最小外壳吗?(我无法在这一秒尝试尝试任何一种。)
Ulrich Schwarz 2015年

感谢Ulrich,Solaris可能正是这种长语法仍然存在的罪魁祸首。
Thorsten Staerk

Answers:


20
export foo=bar

不受Bourne Shell的支持(Bourne Shell是70年代的旧外壳,现代sh实现如ash / bash / ksh / yash / zsh源自该外壳)。由引入ksh

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

foo=bar export foo

要么:

foo=bar; export foo

或搭配set -k

export foo foo=bar

现在,以下行为:

export foo=bar

外壳之间会有所不同。

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

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

例如,

a='b c'
export d=$a

被解释为:

'export' 'd=b' 'c'

带有一些shell(ashzsh(在sh仿真中的旧版本)yash)和:

'export' 'd=b c'

在别人(bashksh)。

export \d=$a

要么

var=d
export $var=$a

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

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

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

Bourne语法如下:

d=$a; export d

所有shell都可以毫无歧义地对其进行相同的解释(d=$a export d也可以在Bourne shell和POSIX兼容shell中使用,但zsh除非是在sh仿真中,否则在最新版本中不能使用)。

比这更糟的是。例如bash参见有关何时涉及数组的最新讨论

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


令我感到惊讶的是foo=bar export foo,因为我一直在那看到它,所以不需要在其中使用分号。我知道导出是内置函数,但是为什么foo=bar; foo=baz export foo; echo $foo行为不同于foo=bar; foo=baz /bin/cat /dev/null; echo $foo
jrw32982支持Monica 2015年

3
@ jrw32982,因为它是内置的。你仍然可以在现代POSIX炮弹,但仅适用于特殊的内置命令export是。
斯特凡Chazelas

尽管它declare没有讨论,但export我还是建议任何关心安全性的人阅读StéphaneChazelas提供给bash.bugs的链接上的讨论。
John1024

好答案!但是花了很长时间d=$a export d
才被

@conny d=$a export d在中不再起作用zsh,所以我更新了答案。参见编辑。
斯特凡Chazelas

28

它不是bashism,而是POSIX兼容的语法。实际上,它早在很久以前就已是一种kshism,后来被几乎所有基于Bourne语法的shell所采用。唯一臭名昭著的例外是/bin/sh在Solaris 10和更早版本的Solaris上,它遵循传统的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发行版进行编译。


非常感谢您对Google的历史了解和正确的错误消息!回想起来很明显,脸红……
三胞胎2015年

4
那不是原始Bourne shell的源代码,而是经过修改的OpenSolaris sh。它是伯恩贝壳,但经过数十年的进化。原来Bourne shell中,作为附带的Unix V7可以发现在Unix的遗产协会
斯特凡Chazelas

1
@StéphaneChazelas严格来说,您像往常一样正确。但是请注意,我不是写“原始的Bourne shell”而是“原始的Bourne shell”,因为我指的是Solaris 10使用的shell及其可在现代平台上编译的源代码。还要注意,Bourne shell在1977年至1989年之间增加了几个功能,但是在过去的25年左右的时间里基本上停止了发展(除了移植/适应较新的平台和错误修复)。
2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.