为什么我不能 cd 到带引号的波浪号 (‘~’)?

为什么我不能 cd 到带引号的波浪号 (‘~’)?

我正在编写我的第一个脚本,所以我确定这是一个基本问题,但是有人可以向我解释为什么我可以:

cd ~
cd bin
cd ~/bin
cd 'bin'

但不是

cd '~'
cd '~/bin'

我需要cd转到目录路径,其中一个目录名称中有空格,因此我需要引号(这是Program FilesWine 下的 Windows)。我可以用两个命令来解决这个问题cd,但为什么我不能加上~引号呢?

如果我输入cd '~'(或cd "~") 我会得到:

bash: cd: ~: No such file or directory

答案1

正如 @karel 在他的回答中指出的那样,~是一个特殊字符,并由 Bash 扩展到当前用户的主目录中。请参阅Bash 的“波浪线扩展”手册,或者在手册页 () 中搜索标题“Tilde Expansion” man bash

周围的任何类型的引用~都会阻止这种波浪符号的扩展。


为了回答您的问题,关于如何仍然可以使用它进入cd名称中带有空格的目录,有几种替代方法:

  • 省略引号并使用反斜杠转义空格:

    cd ~/foo/spaces\ are\ cool/bar
    
  • 引用路径的其余部分,但省略波浪号和第一个斜杠周围的部分:

    cd ~/"foo/spaces are cool/bar"
    

    如您所见,您可以在 Bash 中连接带引号和不带引号的字符串,只需将它们写在一起即可,中间不加任何空格。

  • 使用环境变量$HOME代替波浪号,它仍然会在“双引号”内扩展(但不会“单引号”):

    cd "$HOME/foo/spaces are cool/bar"
    

答案2

~ 是一个特殊字符,shell 将其解释为登录用户的主目录。'~' 被 shell 解释为文字 ~ 字符,而不是登录用户的主目录,因为将字符串括在两个单引号字符内会导致该字符串被解释为文字文本字符串。

答案3

这是一项bash称为波浪号扩展. 引用man bash

如果一个单词以不带引号的波浪符号(`~'),第一个未加引号的斜杠前面的所有字符(如果没有未加引号的斜杠,则为所有字符)都被视为波浪号前缀。如果波浪号前缀中的任何字符都没有加引号,则波浪号后面的波浪号前缀中的字符将被视为可能的登录名。如果此登录名为空字符串,则波浪号将替换为 shell 参数 HOME 的值。如果未设置 HOME,则将替换为执行 shell 的用户的主目录。

为了使扩展工作,波浪符号~需要取消引用,否则该字符将按字面意思理解,如果当前目录中cd没有名为的目录,则扩展会失败。请参阅~这个详尽的答案有关引用的解释,请参阅bash。如果您需要引用部分路径,则可以:

  1. 至少用单引号引用需要引用的字符,例如

    ~/dir' 'with' 'spaces/
    

    或者

    ~/'dir with spaces/'
    
  2. 至少用双引号引用需要引用的字符,例如

    ~/dir" "with" "spaces/
    

    或者

    ~/"dir with spaces/"
    
  3. 仅引用需要用反斜杠引用的字符,例如

    ~/dir\ with\ spaces/
    

Tilde Expansion 还有一些更有趣的功能,例如:

  • ~+扩展为 的值PWD,即当前工作目录
  • ~-扩展为 的值OLDPWD,即上一个工作目录
  • ~john扩展到与登录名“john”关联的主目录

答案4

echo使用命令进行探索

探索 Bash 工作原理的最简单方法是使用echo命令。在这种情况下~使用这个:

$ echo ~
/home/rick
$ echo '~'
~
$ echo "~"
~
$ echo `~`
bash: /home/rick: Is a directory

如您所见,当您使用单引号或双引号时,~它会被逐字解释为字符串,而不是扩展为变量。当您使用反引号 (`) 时,它会作为命令执行并生成错误消息。

相关内容