我正在清理我的所有配置文件,以使它们尽可能可读。我一直在寻找关于在导出路径时使用引号的样式指南,例如,~/.bashrc文件:
export PATH="/users/me/path:$PATH"
对比
export PATH=/users/me/path:$PATH
Google shell 样式指南建议避免路径名使用引号。相比之下,许多流行的 dotfiles 存储库(例如 Zach Holman 的此处)使用引号。在路径中使用引号是否有优势?
向@gniourf_gniourf和@chepner 致敬以寻求帮助。
tl;博士
为了安全起见,双引号:它适用于所有情况,适用于所有类似 POSIX 的 shell。
如果要添加~基于 - 的路径,请选择性地保留~/ 未引用的路径以确保~扩展;例如:export PATH=~/"bin:$PATH"。
变量赋值的扩展规则见下文。~
或者,只需$HOME在单个双引号字符串中使用:
export PATH="$HOME/bin:$PATH"
注意:以下适用于bash、ksh和zsh,但不适用于(大部分)严格符合 POSIX 的 shell,例如dash; 因此,当您定位. 时/bin/sh,您必须双引号export. [1]
shexport在这种情况下你可以不用双引号就可以逃脱的原因是POSIX-like shell 中的变量赋值语句解释它们的 RHS与传递给commands的参数不同,如POSIX 规范的第 2.9.1 节所述:
具体来说,即使执行了初始分词,它也仅适用于未扩展的(原始)RHS(这就是为什么您需要在literals中使用空格/元字符引用),而不是其results。
这仅适用于所有类似 POSIX 的 shell中形式的真正赋值语句
<name>=<value>,即,如果变量名之前没有命令名;请注意,这包括附加到命令以为其定义临时环境变量的分配,例如foo=$bar cmd ....
为了安全起见,其他命令上下文中的赋值应始终用双引号引起来:
对于sh(在(大部分)严格符合 POSIX 的 shell 中,例如dash),赋值 withexport被视为常规命令,并且该foo=$bar部分被视为内置函数的第一个参数,export因此被视为通常处理(受结果,也是)。
(POSIX 没有指定任何其他涉及(显式)变量赋值的命令;declare、、typeset和local是非标准扩展)。
bash, ksh, zsh, 在与 POSIX 的一个可以理解的偏差中,将赋值逻辑扩展到export foo=$bar和typeset/declare/local foo=$bar。换句话说:in bash, ksh, zsh,export/typeset/declare/local命令被视为assignments,因此引用不是绝对必要的。
dash,它也选择实现非-POSIXlocal内置[2]
,并没有将分配逻辑扩展到它;然而,它与它的export行为是一致的。传递给env(例如,env foo=$bar cmd ...)的赋值也可以作为命令参数进行扩展,因此需要双引号 - 除了 in zsh。
env行为不同是因为它是一个外部实用程序,而它是一个内置的 shell。
(在涉及未引用的变量引用时,其行为与其他 shell的行为根本不同)。exportkshbashenvexportzsh波浪号 ( ) 扩展在真正的赋值语句~中发生如下:
~需要被unquoted之外,像往常一样,它也只适用:
~; 例如:
foo=~ # same as: foo="$HOME"~开始字符串或前面有一个不带引号的 :~后跟一个未引用 /的.foo=~/bin # same as foo="$HOME/bin"foo=$foo:~/bin # same as foo="$foo:$HOME/bin"例子
这个例子展示了 in bash, ksh, 并且你可以不用zsh双引号就可以逃脱,即使使用,但我不推荐它。export
#!/usr/bin/env bash
# or ksh or zsh - but NOT /bin/sh!
# Create env. variable with whitespace and other shell metacharacters
export FOO="b:c &|<> d"
# Extend the value - the double quotes here are optional, but ONLY
# because the literal part, 'a:`, contains no whitespace or other shell metacharacters.
# To be safe, DO double-quote the RHS.
export FOO=a:$foo # OK - $FOO now contains 'a:b:c &|<> d'
[1] 正如@gniourf_gniourf 指出的那样:使用 ofexport来修改的值PATH是可选的,因为一旦将变量标记为导出,您就可以使用常规赋值 ( PATH=...) 来更改其值。
也就是说,您仍然可以选择使用export,以便明确表示正在修改的变量已导出。
[2] @gniourf_gniourf 声明 POSIX 标准的未来版本可能会引入local内置函数。
在 docker .env 文件中设置环境路径名时,我使用了上面的这些答案,并且有点。我把这个放在这里是为了给其他寻找如何为 docker 定义环境变量的人。
Docker compose 从 .env 文件中读取环境变量,该文件位于运行 docker compose 的同一文件夹中,如此处所述https://docs.docker.com/compose/env-file。
但是,docker compose 不需要将值包装在引号中,而是需要在没有引号的情况下定义环境变量,除非引号是值的一部分。同样,如上面的网址所述
引号没有特殊处理(即它们将成为 VAL 的一部分,您已被警告;)
我试图设置NODE_PATH=./src绝对路径以在 docker 部署的反应应用程序中工作,但已将其编写为NODE_PATH="./src". 这个警告把我从 4 小时的兔子洞里拉了出来。
test 123是 UNIX 上的有效路径名。尝试
PATH=test 123
它将返回:
123: command not found
甚至
export PATH=test 123
这将返回
bash export: `123': not a valid identifier
它回答了你的问题吗?
老实说,我不会遵循这样的第四方风格指南。虽然我很惊讶,即使是谷歌也宣传了这样的错误建议。
我会遵循:
(需谨慎扩展)