在环境变量的值中使用美元符号是一种不好的做法吗?
前任:
MY_VAR="$toto"
更准确地说,我想将其设置/etc/environment
为可通过 Java 程序访问的文件中。我进行了测试,它运行正常,但我只是想确保不会遇到任何灾难性的副作用。变量的值是密码,以美元符号开头,所以我别无选择。
答案1
你的例子没有说明你的问题。
$ toto="somevalue"
$ MY_VAR="$toto"
$ echo $MY_VAR
somevalue
$
要完成你要求的事情,你需要:
MY_VAR='$toto'
或者
MY_VAR="\$toto"
不能确定这是否是不好的做法。我个人认为没有发现任何明显问题。
答案2
许多人指出,如果未设置,将分配给当前值或空字符串(或者显然如果MY_VAR="$toto"
本身MY_VAR
包含空字符串),但我很惊讶没有人指出$toto
$toto
$toto
MY_VAR="$toto"
不是MY_VAR
设置环境变量而是设置 shell 变量(除非环境中已经存在名为的变量,可能是因为这只是与实际问题无关)。
然而更重要的是,这不是一个坏习惯,或者它和在变量内有任何其他 shell 特殊字符一样坏习惯,这通常是无法避免的。
在 99% 的情况下,shell 会在当前 shell 中扩展变量只有一次(或者根本不会扩展它,例如用单引号引起来时):
$ MY_VAR='$toto'
$ echo $MY_VAR
$toto
$ echo '$MY_VAR'
$MY_VAR
$ echo "$MY_VAR"
$toto
$ echo $(echo $MY_VAR)
$toto
例如,1% 的情况是,当变量在表达式中被引用时eval
,这会增加一个间接级别:
$ MY_VAR='$toto'
$ eval echo $MY_VAR
$
但这显然是预期的结果,同样,在变量内部包含任何其他 shell 特殊字符也应被视为一种不好的做法:
$ MY_VAR='&&'
$ eval echo $MY_VAR
bash: syntax error: unexpected end of file
(事实是使用eval
正因为如此,这通常是一种不好的做法。
因此,在 shell / 环境变量中使用美元符号并不是一个坏习惯,至少不比任何其他 shell 特殊字符更糟糕。
答案3
对于特定情况/etc/environment
,$
变量值中的 a 没有任何特殊含义。/etc/environment
是由名为的 PAM 模块读取的文件pam_env
,并且pam_env
有特定的解释语法$
:
- 在 中
/etc/environment
,它未被解释。 在
/etc/security/pam_env.conf
和~/.pam_environment
(用户特定文件)在看到具有以下语法的行时会进行特殊pam_env
处理:$
FOO DEFAULT=SOMETHING${BAR}SOMETHINGELSE$BAR FOO OVERRIDE=SOMETHING${BAR}SOMETHINGELSE$BAR
在这种情况下,
${BAR}
被替换为变量 的值BAR
,但没有$BAR
。
在这两种情况下,对于如下行:
FOO=BAR$BAR${BAR}
变量的内容FOO
将是文字字符串BAR$BAR${BAR}
。
手册pam_env.conf
页中有示例:
Silly examples of escaped variables, just to show how they work.
DOLLAR DEFAULT=\$
DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR}
DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST}
ATSIGN DEFAULT="" OVERRIDE=\@
答案4
回答您的确切问题:
是的,在环境变量的值中使用美元符号是一种不好的做法。但是,您显示的代码片段实际上并不是这样做的。
MY_VAR="$toto"
$
是你的 shell 中的一个特殊字符(无论是bash
或dash
),并且除非受到变量扩展保护,否则你实际上不会在 的值中放置一个文字美元符号MY_VAR
。
要做到这一点,您需要对 进行转义$
,可以在其前面加上反斜杠,也可以在其两边加上单引号。