'cd' 和 'cd ~' 之间的区别

Lui*_*ado 13 cd-command home

我想知道,如果cd单独将我发送到我的主文件夹,而cd ~也是如此,那么为什么 ~ 是首先添加的?

它是 BASH 特有的,还是它们在另一个 Shell 中的行为会有所不同?

ahi*_*end 18

~用途不止于此。任何命令都可以从主文件夹的快捷方式中受益。因此,如果您想 cd 进入您的家,则没有必要,但是呢~/.config

$ cd ~/.config
Run Code Online (Sandbox Code Playgroud)

否则,您必须写出主路径,使用$HOMEvar 或执行两个cds。也用于复制或移动文件:

$ cp ~/downloads/some-file some/path/
Run Code Online (Sandbox Code Playgroud)

由于您的大部分文件都在家里,因此拥有快捷方式总是好的。

  • @CYREX 我的猜测是为想要移动到主目录的非常常见的情况节省输入。 (4认同)

Ser*_*nyy 6

这样做cd 基本上是cd在不带参数的情况下调用,并根据cd行为“...如果未提供 dir,则 HOME shell 变量的值是默认值。” (来自bash 手册)。相比之下,cd ~当您向cdcommand提供参数时,恰好是~shell 将执行波浪号扩展。至于返回用户的主目录 - 没有区别。无论哪种情况,HOME都会查询环境变量:

$ env 'HOME=/usr' bash -c 'cd;pwd; cd ~;pwd'                                      
/usr
/usr
Run Code Online (Sandbox Code Playgroud)

实际上,这也与cd $HOME. 然而,虽然cd只能做一件事,但波浪号可用于执行其他扩展,例如~+当前工作目录。

然而,有趣的是,我们可以unset HOME打破cd~仍然有效:

$ bash -c 'cd /usr;unset HOME;cd;pwd;cd ~;pwd'                                    
bash: line 0: cd: HOME not set
/usr
/home/xieerqi
Run Code Online (Sandbox Code Playgroud)

为什么 ?再次,在手册中回答:

如果未设置 HOME,则会替换执行 shell 的用户的主目录。否则,波浪号前缀将替换为与指定登录名关联的主目录。

请注意,取消设置与创建空变量不同,HOME=并且确实有效。文档专门讨论了取消设置变量。使变量等于空字符串的效果与我们预期的相反:

bash-4.3$ env 'HOME=' bash -c 'cd /usr;set|grep "^HOME"; stat -c "%F" ~;cd;pwd'
HOME=
stat: cannot stat '': No such file or directory
/usr
Run Code Online (Sandbox Code Playgroud)

在这里您可以看到,创建HOME空字符串会破坏波浪号和cd行为。


波浪号和$HOME有一些区别和不同的存在理由。$HOME是一个 shell 变量,碰巧它也是环境变量之一——它对所有程序都可用;在 C 中,您将使用它environ()来访问它。相比之下,tilde执行波浪号扩展的是特定于 shell 的语法,尽管您也可以使用wordexp()函数在 C 中执行类似 shell 的扩展(参考)。

~代表的原因HOME已在此问题中得到解答:曾几何时,波浪号字符与HOMELear-Siegler ADM-3A 终端上共享相同的密钥。HOME相比之下,环境变量具有纯粹的象征意义,没有物理表示。

此外,HOME作为环境变量的事实允许我们取消设置它,因为我们无法~通过简单的方式设置为其他内容。

# cd ~ will still work, because ~ is blank, so it's same as just cd
$ bash -c 'unset HOME; echo $HOME; cd ~;pwd'                           

/home/xieerqi
$ env 'HOME=' bash -c 'echo $HOME; cd ~;pwd'                                

/home/xieerqi
Run Code Online (Sandbox Code Playgroud)

请注意首先echo输出未设置变量的空行,以及 . 相比之下,我们不能做这样的事情来波浪号:

$ bash -c '~=; cd ~;pwd'                                                    
bash: ~=: command not found
/home/xieerqi
$ bash -c '~=$'\0'; cd ~;pwd'                                               
bash: ~=bash: command not found
/home/xieerqi
$ bash -c 'unset ~; cd ~;pwd'                                               
bash: line 0: unset: `/home/xieerqi': not a valid identifier
/home/xieerqi
Run Code Online (Sandbox Code Playgroud)

但是,更改HOME确实会影响~

$ env 'HOME=' bash -c 'echo $HOME; stat ~;'                                 

stat: cannot stat '': No such file or directory
Run Code Online (Sandbox Code Playgroud)

另外,因为~也可以作为扩展符,我们可以做这样的事情来显示当前工作目录:

$ bash -c 'cd /etc/;stat -c "%n" ~+'                                        
/etc
Run Code Online (Sandbox Code Playgroud)

而如果我们想通过环境变量来做到这一点,我们需要PWD, 并且HOME保持不变,或者如果你做这样的事情echo $HOME+- 那只是字符串/变量连接。但同样,~+从环境变量中提取信息:

$ bash -c 'cd /etc/;PWD="/usr";stat -c "%n" ~+'                             
/usr
Run Code Online (Sandbox Code Playgroud)

注意~+~-扩展kshdash.


要回答您的一些具体问题:

它是 BASH 特有的,还是它们在另一个 Shell 中的行为会有所不同?

不,这应该是一致的行为。ksh, dash, 和csh- 都与cdor 的行为相同cd ~

为什么 ~ 是首先添加的?

我会说方便和历史原因,如有关波浪号的链接答案中所述。最终,它变得不仅仅是主目录扩展。