我正在清理所有配置文件,试图让它们尽可能可读。我一直在寻找关于在导出路径时使用引号的样式指南,例如~/.bashrc
文件:
export PATH="/users/me/path:$PATH"
vs
export PATH=/users/me/path:$PATH
Google shell style指南建议避免使用路径名称的引号。相比之下,很多流行的dotfiles回购(例如Zach Holman的here)都使用引号。在路径中使用引号是否有利?
答案 0 :(得分:18)
向@gniourf_gniourf和@chepner求助的提示。
<强> TL;博士强>
为了安全起见,双引号:它可以在所有类似POSIX的shell中工作。
如果您想添加基于~
的路径,有选择地保留~/
不加引号以确保~
是扩大;例如:export PATH=~/"bin:$PATH"
。
请参阅下文,了解变量赋值中~
扩展的规则。
或者,只需在单个双引号字符串中使用$HOME
:
export PATH="$HOME/bin:$PATH"
注意:以下内容适用于 bash
,ksh
和zsh
,但不适用于(大多数)严格遵守POSIX的shell,例如{{1 }};因此,当你定位dash
时,你必须双引用/bin/sh
的RHS。 [1]
export
时, 与sh
有关,所以总是在那里加双引号。在这种情况下你可以在没有双引号的情况下离开的原因是类似POSIX的shell中的 变量赋值语句以不同的方式解释它们的RHS em> arguments 传递给命令 ,如POSIX规范section 2.9.1中所述:
具体来说,即使执行初始分词 ,它也仅适用于未扩展(原始)RHS(这就是 / LI>
此仅适用于形式
的正版赋值语句
所有类似POSIX的shell 中的export
,即,如果变量名称前面没有 no命令名称;请注意,这包括 prepended 分配给命令以为其定义ad-hoc环境变量,例如<name>=<value>
。
在其他命令的上下文中分配应该始终是双引号,以确保安全:
使用foo=$bar cmd ...
(在(大部分)严格遵守POSIX的shell中,例如sh
),dash
的作业被视为常规命令,export
部分被视为foo=$bar
内置的第一个参数,因此照常处理(受结果的分词影响< / em>,也是。)
(POSIX没有指定涉及(显式)变量赋值的任何其他命令; export
,declare
和typeset
是非标准扩展)。< / p>
local
,bash
,ksh
,与POSIX理解偏差,将分配逻辑扩展到zsh
和export foo=$bar
。换句话说:typeset/declare/local foo=$bar
中的,bash
,ksh
,zsh
命令被视为分配,因此引用不是&#39严格必要。
export/typeset/declare/local
,它也选择实现非 -POSIX dash
内置 [2]
,不会将赋值逻辑扩展到它;但是,它与local
行为一致。传递给export
的作业(例如env
)也会作为命令参数进行扩展,因此需要双引号 - env foo=$bar cmd ...
除外。
zsh
env
与export
ksh
的行为与bash
的行为不同,因为env
是外部效用,而export
是 shell内置
(zsh
的行为从根本上与其他shell的行为不同,当涉及到不带引号的变量引用时。) Tilde(~
)扩展在正版分配声明中发生如下:
~
需要不加引号之外,像往常一样,它也只适用于:
~
;例如。:
foo=~ # same as: foo="$HOME"
~
启动字符串或前面带有未加引号 :
~
后跟未加引号 /
。foo=~/bin # same as foo="$HOME/bin"
foo=$foo:~/bin # same as foo="$foo:$HOME/bin"
示例强>
此示例表明,在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所指出的:使用export
修改 PATH
的值是可选的,因为一旦变量被标记为已导出,您可以使用常规作业(PATH=...
)来更改其值
也就是说,您仍然可以选择来使用export
,以便明确表达要修改的变量。
[2] @gniourf_gniourf声明POSIX标准的未来版本可能会引入local
内置。
答案 1 :(得分:2)
test 123
是UNIX上的有效路径名。尝试
PATH=test 123
它将返回:
123: command not found
甚至
export PATH=test 123
将返回
bash export: `123': not a valid identifier
它能回答你的问题吗?
老实说,我不会遵循这样的第四方风格指南。虽然我很惊讶,即使谷歌也会宣传这些错误的建议。
我会跟着:
(小心延伸)
答案 2 :(得分:2)
我在docker .env文件中设置环境路径名时使用了以上这些答案,并得到了一点。我正在为其他任何人寻找如何为docker定义环境变量。
Docker compose从.env文件中读取环境变量,该文件存在于docker撰写的同一文件夹中,如此处所述https://docs.docker.com/compose/env-file.
但是,除非将引号作为值的一部分,否则docker compose不需要将值包装在引号中,而是需要使用不带引号定义的环境变量。再次,如上面的网址所述
没有特别处理引号(即它们将是 VAL的一部分,你已被警告;)
我试图将NODE_PATH=./src
设置为在docker部署的react应用程序中工作的绝对路径,但是已将其写为NODE_PATH="./src"
。这个警告把我拉出了4个小时的兔子洞。