我在 .profile 中定义了一些环境变量,如下所示:
MY_HOME="/home/my_user"
但除非我去掉引号并重新获取文件,否则该变量似乎不会计算。我相信如果有空格,引号是必要的,如果不需要转义,则使用单引号。有人可以澄清变量定义中单引号和双引号的重要性吗?前勾号和后勾号怎么样?
答案1
我认为您对术语感到困惑。
“环境变量”只是任何子进程都会继承的 shell 变量。
您在示例中所做的是创建一个 shell 变量。在导出之前它并不在环境中:
MY_HOME="/home/my_user"
export MY_HOME
在几乎所有 shell(csh、tcsh 除外)中放置一个名为“MY_HOME”的变量。
在这种特殊情况下,双引号是多余的。它们没有任何作用。双引号将子字符串分组,但允许您使用任何 shell 进行变量替换。单引号对子字符串进行分组并防止替换。由于您的示例赋值中没有任何变量,因此双引号可能显示为单引号。
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
在导出之前,环境中没有任何内容。
答案2
shell 变量与环境变量
MY_HOME="/home/my_user"
设置外壳变量叫MY_HOME
. Shell 是编程语言,并且具有变量(也称为参数)。分配后,您可以使用变量的值,例如使用echo "$MY_HOME"
。
Shell 变量是一个内部 shell 概念。当该 shell 实例终止时,MY_HOME
就会被遗忘。每个程序都知道并传输给它的孩子的是环境变量。
在 shell 内部,环境变量和 shell 变量的工作方式非常相似。实际发生的情况是,shell 从其父级继承的所有环境变量都成为 shell 变量。相反,在 shell 脚本中定义的 shell 变量将成为环境变量,如果您出口它。
export MY_HOME="/home/my_user"
更多细节您可以在第一次阅读时跳过
shell 变量不会自动成为环境变量的原因部分是脚本可能会意外使用对其启动的程序有意义的变量名称,部分原因是历史变量。
每次更改变量名称时都需要使用一些非常古老的 shell export
,但所有现代 shell 都会跟踪环境变量的分配,因此以下代码片段会回显bar
:
myvar=foo
export myvar
myvar=bar
env | grep '^myvar='
此外,一些非常古老的 shell 需要单独的命令myvar=foo
和export myvar
,但所有现代 shell 都理解export myvar=foo
。
你可以运行set -a
使所有 shell 变量分配自动导出变量,因此myvar=foo
相当于export myvar=foo
您set -a
首先在该 shell 中运行。
关于引用
引用大多是正交的。如果分配给变量的值不包含任何 shell 特有的字符,则不需要任何引号。如果有特殊字符,则需要用单引号或双引号或反斜杠或其组合来保护它们。这适用于简单myvar=value
语法和export
实用程序。
赋值语法和赋值export
语法之间有一处区别。 shell$foo
进一步扩展变量替换的结果,执行字段(词)分割和路径名扩展(通配)。这意味着如果 的值为myvar
,hello *
则echo $myvar
打印hello
后跟一个空格,后跟当前目录中的文件列表。这几乎是不可取的,因此一般原则是始终在变量替换周围使用双引号(除非您知道需要路径名扩展或字段分割):echo "$myvar"
.在简单赋值的情况下,othervar=$myvar
实际上可靠地复制myvar
to的值othervar
,因为赋值中禁止通配符和分词(因为它们创建多个单词,但期望单个单词)。然而,这种豁免不适用于export
。因此,如果您想记住一个简单的规则,只需始终在变量替换周围使用双引号即可。