给定目录:/media/foo/can haz/bar
,我尝试编辑根目录和:
export Foo=/media/foo/can haz/bar
export Foo=/media/foo/can\ haz/bar
export Foo='/media/foo/can haz/bar'
export Foo="/media/foo/can haz/bar"
export Foo='"/media/foo/can haz/bar"'
export Foo="'/media/foo/can haz/bar'"
但每次,我都无法使如下内容工作(不使用"$Foo"
):
cd $Foo
如何在 Linux 系统上设置带有空格的环境变量?
答案1
问题不在于你的环境变量包含空格。你忘记了引用你的论点:
cd "$Foo"
如果不引用$Foo
,该cd
命令实际上将看到两个(或更多)参数,因为默认情况下,空格分隔参数。在您的特定情况下,您需要分别传递/media/foo/can
和haz/bar
,因为 shell 会在空格处将它们分开。使用双引号括住变量是一个好习惯,在涉及空格的很多情况下,它都会为您节省时间。
如果您想要一种不使用引号的非常丑陋的方法来实现这一点,请cd
像这样覆盖您的内置函数:
cd() { builtin cd "$*"; }
如果路径包含空格,这将起作用,因为将包含由第一个 IFS 字符(通常是空格)分隔的$*
各个参数(/media/foo/can
和),然后使用双引号将它们粘合在一起。haz/bar
然而,像这样覆盖内置命令永远不是一个好主意。
答案2
正如 @slhck 所说,正确的方法是在变量引用周围加上双引号(例如cd "$Foo"
)。 这样做的原因是 shell 解析命令行各个方面的顺序:首先扫描引号和转义符(并在应用它们的效果时删除它们),然后用它们的值替换变量引用(例如$Foo
-> /media/foo/can haz/bar
),然后它返回替换的值并应用通配符扩展(*.txt
->a.txt b.txt
等)和单词拆分(/media/foo/can haz/bar
-> “/media/foo/can” “haz/bar”),但它永远不会返回并在变量值中查找引号和/或转义符。 因此,在变量的值中嵌入引号和/或转义符毫无用处;当它们成为命令行的一部分时,它们已经太晚了,无法产生预期的效果。我只知道三种方法可以避免在扩展值上进行分词:
- 用双引号括住变量引用。虽然不太方便,但这是标准 shell 语法的要求。
- 更改 IFS 的值(用于扩展变量上的分词的字符列表)。然后观察所有依赖于标准分词行为的脚本是否出现奇怪的中断。请不要这样做。说真的。
- 切换到不对扩展变量进行分词的 shell:zsh。您必须习惯它与 bash 的其他差异,但如果您真的想要这个,这是最好的方法。我自己不使用它,但那些使用它的人似乎非常喜欢它...