我想知道,如果cd单独将我发送到我的主文件夹,而cd ~也是如此,那么为什么 ~ 是首先添加的?
它是 BASH 特有的,还是它们在另一个 Shell 中的行为会有所不同?
ahi*_*end 18
的~
用途不止于此。任何命令都可以从主文件夹的快捷方式中受益。因此,如果您想 cd 进入您的家,则没有必要,但是呢~/.config
?
$ cd ~/.config
Run Code Online (Sandbox Code Playgroud)
否则,您必须写出主路径,使用$HOME
var 或执行两个cd
s。也用于复制或移动文件:
$ cp ~/downloads/some-file some/path/
Run Code Online (Sandbox Code Playgroud)
由于您的大部分文件都在家里,因此拥有快捷方式总是好的。
这样做cd
基本上是cd
在不带参数的情况下调用,并根据cd
行为“...如果未提供 dir,则 HOME shell 变量的值是默认值。” (来自bash 手册)。相比之下,cd ~
当您向cd
command提供参数时,恰好是~
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
已在此问题中得到解答:曾几何时,波浪号字符与HOME
Lear-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)
注意:~+
和~-
扩展ksh
在dash
.
要回答您的一些具体问题:
它是 BASH 特有的,还是它们在另一个 Shell 中的行为会有所不同?
不,这应该是一致的行为。ksh
, dash
, 和csh
- 都与cd
or 的行为相同cd ~
。
为什么 ~ 是首先添加的?
我会说方便和历史原因,如有关波浪号的链接答案中所述。最终,它变得不仅仅是主目录扩展。