为什么 `env var=value` 允许 var 中任意名称?

为什么 `env var=value` 允许 var 中任意名称?

阅读env POSIX 文档:

有些人认为 env 是多余的,因为通过以下方式可以达到相同的效果:

名称=值...实用程序[参数...]

当将环境变量添加到命令的环境中时,该示例相当于 env,但当环境设置为给定值时则不同。如果不带参数调用,env 实用程序还会写出当前环境。除了示例提供的功能之外,还有足够的功能来证明包含 env 的合理性。

AFAICT,当使用 as 时,上述语句的含义var=value command与 相同,而 则不同。env var="value" commandenv -i var="value" command

现在,至少在envGNU 系统、FreeBSD 和 Solaris 11 上的实现中,我意识到它们是不等价的,因为env允许任何字符,除了名称中的=和:\0var

$ env 'BASH_FUNC_foo%%=() { echo foo; }' bash -c foo

打印,虽然您不能BASH_FUNC_foo%%='() { echo foo; }'在任何 shell 中使用,因为BASH_FUNC_foo%%显然不是有效的变量名。

在 POSIX shell 中,除了 之外bash,这会留下一个在环境变量中命名的变量BASH_FUNC_foo%%,shell 无法访问它。

那么,允许表单中任意名称的目的是什么env var=value?POSIX 是否允许这样做?

答案1

那么,允许表单中任意名称的目的是什么env var=value?POSIX 是否允许这样做?

引用自POSIX:环境变量:

POSIX.1-2008 的 Shell 和实用程序卷中的实用程序使用的环境变量名称仅由大写字母、数字和可移植字符集中定义的字符中的 ( '_' ) 组成,并且不以数字开头。实现可能允许其他字符;应用程序应容忍此类名称的存在。

注意:其他应用程序可能难以处理以数字开头的环境变量名称。因此,不建议在任何地方使用此类名称。

因此, 的实现env可能允许任意环境变量名称 - 并且大多数(如果不是全部)实现都这样做,接受 an 左侧的每个非 NUL 字符'='- 并且其他实用程序(例如 shell)的实现可能允许也可能不允许任意环境变量名称名称。

仅当 的实现和 shell 都允许作为环境变量时,name=value ... utility相当于 的语句才为真。env var="value" utilityenvname

奥斯汀集团有一个关于这个问题的有趣帖子:环境中的 shell 分配无效。提到的一点是,shell 通常只允许名称可以表示为 shell 变量的环境变量。该线程中的多个参与者参与了 unix.stackexchange.com,并有望添加有关该问题的更多信息。

答案2

你是真的,env允许你将东西放入可能对 shell 无效的环境中。我认为这个事实没有问题,因为它env是一个单独的程序,并且环境不限于 shell 接受的内容shell variables

仔细查看结果会发现,常用 shell 的行为方式都不会导致无法访问 shell 变量:

  • Bourne Shell 根本不导入或传播此类变量

  • ksh(自 ksh88 以来的所有版本)和 zsh 仅将变量保留在环境中,但不将它们传播到 shell 变量列表

唯一有问题的 shell 似乎是bash因为它将环境导入到 shell 变量列表中,但不允许访问相关的 shell 变量。

我建议您针对 bash 进行错误报告。

相关内容