为什么我不能使用加引号的波浪号('〜')?


32

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

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

但不是

cd '~'
cd '~/bin'

我需要cd使用目录名称之一中带有空格的目录路径,因此我需要使用引号(Program Fileswine下是Windows )。我可以用两个cd命令解决它,但是为什么不能加~引号呢?

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

bash: cd: ~: No such file or directory

29
问问自己:如果不是这样,您cd将如何进入名为的目录~
约尔格W¯¯米塔格

2
附带一提,如果您要编写脚本,则应使用绝对路径并避免全部使用cd。使用变量存储您不想多次键入的路径名,例如pf=~/.wine/drive_c/Program\ Files/; cp /path/to/file "$pf"
甜点

8
@jamesqf:为什么一个明智的系统会假定比我更了解我想为文件和目录命名的内容?而且,我从来不明白为什么Unix会使用路径组件分隔符和路径终止符的魔术带内信令。名为/或的文件/目录有什么问题NUL
约尔格W¯¯米塔格

3
@JörgWMittag大概cd ./~
k_g

2
@jamesqf请注意,从历史上看,Unix文件系统允许文件名中的任何char除'/'(路径分隔符)和'\ 0'(NUL-字符串终止char)之外(如Jorg所述)。没有其他限制。Unix文件系统有很多实现,因此在其中任何一个中引入限制都会破坏兼容性并增加复杂性-被视为“怪异”!而且,'〜'扩展只是最近才在csh中引入,而在bash中更广泛地引入,不知道带有'〜'字符的文件/目录(例如myfile〜作为myfile的备份)。
苏珊·W

Answers:


78

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

周围的任何形式的引号均会~阻止代字号扩展。


要回答有关如何仍将其用于cd名称中带有空格的目录的问题,有几种选择:

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

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

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

    如您所见,您可以将Bash中带引号和未引号的字符串连接在一起,方法是简单地将它们彼此相邻地写,而在两者之间没有任何空格。

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

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

3
@rexkogitans ~'/...'不起作用,也不是这个答案。~/'...'~/"..."会工作。
好莱坞

tld; dr:因为多数民众赞成在shell语法
Sergiy Kolodyazhnyy

@hvd谢谢。固定错别字。这是最完整的答案,还说明了如何解决OP要做的事情。~/'path'是要走的路。
rexkogitans

1
@hvd很少好奇,为什么~'/...'不起作用?斜杠不是特殊字符,因此它似乎应该在引号内或引号外起作用。
科多斯·约翰逊

6
@KodosJohnson看看Bash联机帮助页上有关“波浪扩展”的部分。下文的甜点答案中也引用了其中的相关段落。TL; DR:如果单词中的第一个字符是未加引号的波浪号,则将进行波浪号扩展,然后将该波浪号与下一个未加引号的斜杠之间的所有内容都视为“波浪号前缀”。如果此前缀不是有效的前缀,例如+,-,数字或用户名(也不允许使用引号),则扩展失败,您将获得一个文字〜字符。
字节指挥官

17

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


~从某种意义上bash说,它不是别名:别名允许在将字符串用作简单命令的第一个单词时将其替换为单词。。正如我在下面的回答中所解释的,这是一种扩展。
甜点

15

这是一个bash称为Tilde Expansion的功能。引用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”关联的主目录

顺便说一句,也可以用反斜杠“过度引用”。例如$ touch a; cd \a。(我认为这可能cd \nbash
会给您带来

1

使用echo命令探索

探索事物如何在bash中工作的最简单方法是使用echo命令。在~使用的情况下:

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.