我在.profile中定义了一些环境变量,如下所示:
MY_HOME="/home/my_user"
但是除非我去除引号并重新获取文件,否则该变量似乎不会求值。我相信,如果有空格,则必须使用引号;如果不希望使用转义符,则使用单引号。有人可以澄清变量定义中单引号和双引号的重要性吗?前叉和后叉怎么样?
我在.profile中定义了一些环境变量,如下所示:
MY_HOME="/home/my_user"
但是除非我去除引号并重新获取文件,否则该变量似乎不会求值。我相信,如果有空格,则必须使用引号;如果不希望使用转义符,则使用单引号。有人可以澄清变量定义中单引号和双引号的重要性吗?前叉和后叉怎么样?
Answers:
我认为您对术语感到困惑。
“环境变量”仅仅是任何子进程都将继承的外壳变量。
您在示例中所做的是创建一个shell变量。除非将其导出,否则它不在环境中:
MY_HOME="/home/my_user"
export MY_HOME
在几乎所有外壳程序中都放置一个名为“ MY_HOME”的变量(csh,tcsh除外)。
在这种特殊情况下,双引号是多余的。它们没有作用。双引号将子字符串分组,但允许使用任何用于进行变量替换的外壳程序。单引号将子字符串分组并防止替换。由于示例分配中没有任何变量,因此双引号可能显示为单引号。
V='some substrings grouped together' # assignment
X="Put $V to make a longer string" # substitution and then assignment
Y=`date` # run command, assign its output
Z='Put $V to make a longer string' # no substition, simple assignment
导出之前,环境中什么都没有。
MY_HOME="/home/my_user"
设置名为的shell变量MY_HOME
。外壳程序是编程语言,并且具有变量(也称为参数)。分配后,您可以使用变量的值,例如与echo "$MY_HOME"
。
Shell变量是内部Shell概念。当该shell实例终止时,MY_HOME
将其忘记。每个程序都知道并传递给其子级的是环境变量。
在外壳内部,环境变量和外壳变量的工作方式非常相似。实际上发生的是,外壳程序从其父级继承的所有环境变量都变成了外壳程序变量。相反,如果您导出外壳程序脚本中定义的外壳程序变量,则该变量将成为环境变量。
export MY_HOME="/home/my_user"
Shell变量不会自动成为环境变量的原因部分是因为脚本可能意外地使用了对其启动的程序有意义的变量名,部分原因是历史性的。
export
每次更改变量名称时都需要使用一些非常旧的shell ,但是所有现代的shell都会跟踪环境变量的分配,以便以下代码段回显bar
:
myvar=foo
export myvar
myvar=bar
env | grep '^myvar='
另外,一些非常旧的shell需要为myvar=foo
和提供单独的命令export myvar
,但是所有现代shell都可以理解export myvar=foo
。
您可以运行set -a
以使所有外壳程序变量分配自动导出变量,因此这myvar=foo
等同于export myvar=foo
您set -a
首先在该外壳程序中运行。
报价大多是正交的。如果您要分配给变量的值不包含外壳程序专用的任何字符,则不需要任何引号。如果有特殊字符,则需要用单引号或双引号或反斜杠或其组合来保护它们。这适用于普通myvar=value
语法和export
实用程序。
赋值语法和export
语法之间有一个区别。Shell $foo
进一步扩展变量替换的结果,执行字段(单词)拆分和路径名扩展(globbing)。这意味着,如果值myvar
是hello *
,那么echo $myvar
会打印hello
后跟一个空格,然后是文件的当前目录列表。这是几乎从来没有希望,因此总的原则要始终在用变量替换双引号(除非你知道你需要在路径名扩展或场分裂)echo "$myvar"
。在简单分配的情况下,othervar=$myvar
实际上可靠地将的值复制myvar
到othervar
,因为在分配中禁止使用通配符和单词拆分(因为它们会创建多个单词,但是期望一个单词)。但是,此分配不适用于export
。因此,如果您想记住一个简单的规则,请始终在变量替换周围使用双引号。