在 shell 脚本中执行 "export VAR=value" 是否可移植?

Is it portable to do "export VAR=value" in shell scripts?

我看到很多片段都这样做:

SOME_LONG_VARIABLE_NAME=whatever_value
export SOME_LONG_VARIABLE_NAME

我想知道为什么人们不这样做:

export SOME_LONG_VARIABLE_NAME=whatever_value

我的问题:

  1. 是否需要符合 POSIX 的 shell 来支持 export VAR=value 语法?即,它是否便携?
  2. 如果是这样,为什么这种较短的语法不流行?

如前所述,POSIX requires 支持语法:

export name[=word]...

当然,非 POSIX shell 可能会在此语法上失败,但这超出了 这个问题的范围。上面的语法是可移植的。

"Is it portable" 与 "is it POSIX" 不是同一个问题。 export var=value 由 POSIX 指定,但如果您针对更广泛的所有(当前和遗留)Bourne-like shells.

群体,则它不可移植

我不知道目前是否有供应商销售的系统不允许这种语法。但同样,"systems currently being sold" 和 "systems currently running" 是不同的问题。我们需要一些 AIX、HP-UX、Solaris 等的实际用户来告诉我们...

出于以下任一原因,您可能会发现使用两步 "assign then export" 的脚本:

  1. 该脚本是很久以前写的,此后一直处于维护模式。合并语句将是纯粹的外观更改,这是不可取的。
  2. 该脚本实际上旨在 运行 在某些具有非 POSIX /bin/sh
  3. 的遗留系统上
  4. 作者很久以前就学习了 shell 编程,只是按照习惯做事,知道旧方法(当不与 POSIX 相矛盾时)至少与 POSIX。这种人也可能会看到用expr做算术,可能会出现神秘的构造${1+"$@"}
  5. (最坏的情况)作者在看不懂的情况下抄袭了其他脚本的点点滴滴,而这一段来自于前一类的脚本

这不是答案,但我想提一下我刚刚发现的以下问题。

以下代码片段在 bash 中的行为与在破折号中的行为不同:

names="one two three"
export BOBO=$names
  1. 在 bash 中,变量 BOBO 将按预期包含 "one two three"。
  2. 在短划线中,变量 BOBO 将包含 "one"。换句话说:在 dash 中,"export" 就像一个系统命令(如 lsecho、...),在变量扩展在命令看到它之前执行的意义上。破折号中的命令实际上是 export BOBO=one two three.

(为了使破折号表现得像 bash,我们需要用引号代替 "$names"。或者一开始就不要使用 export var=val syntax。)

local var=$val 存在同样的问题(不在 POSIX 中):你需要将 $val 包装在如果您希望破折号按预期处理它,请加引号。

考虑到 /bin/sh 在流行系统中(如 Ubuntu)实际上是破折号,这是一个巨大的问题。 (不知为何我没听说过!)

编辑:

我看到 "Are quotes needed for local variable assignment?" 中讨论了这个问题。