阅读env POSIX 文档:
有些人认为 env 是多余的,因为通过以下方式可以达到相同的效果:
名称=值...实用程序[参数...]
当将环境变量添加到命令的环境中时,该示例相当于 env,但当环境设置为给定值时则不同。如果不带参数调用,env 实用程序还会写出当前环境。除了示例提供的功能之外,还有足够的功能来证明包含 env 的合理性。
AFAICT,当使用 as 时,上述语句的含义var=value command
与 相同,而 则不同。env var="value" command
env -i var="value" command
现在,至少在env
GNU 系统、FreeBSD 和 Solaris 11 上的实现中,我意识到它们是不等价的,因为env
允许任何字符,除了名称中的=
和:\0
var
$ 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" utility
env
name
奥斯汀集团有一个关于这个问题的有趣帖子:环境中的 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 进行错误报告。