在的情况下csh
和tcsh
,它记录的值$HOME
在壳开始(时间变量在其$home
可变由@JdeBP指出)。
如果您在启动之前取消设置csh
,则会看到类似以下内容的内容:
$ (unset HOME; csh -c cd)
cd: No home directory.
对于bash
(以及大多数其他类似Bourne的贝壳),我看到的行为与您的行为不同。
bash-4.4$ unset HOME; cd
bash: cd: HOME not set
$HOME
变量的内容由登录过程根据用户数据库中存储的用户名信息初始化。
有关用户名本身的信息并非始终可用。Shell只能确定正在执行它的进程的用户ID,并且几个用户(具有不同的主目录)可以共享同一用户ID。
因此,一旦$HOME
消失了,就没有可靠的方法来取回它。
在用户数据库(使用getpwxxx()
标准API)中查询第一个具有与运行Shell的用户具有相同uid的uid的用户的主目录,这只是一个近似值(更不用说用户数据库可能已更改(或主目录)自登录会话开始以来,目录被定义为一个时间值)。
zsh
我知道的唯一的壳就是这样做的:
$ env -u HOME ltrace -e getpw\* zsh -c 'cd && pwd'
zsh->getpwuid(1000, 0x496feb, 114, 0x7f9599004697) = 0x7f95992fddc0
/home/chazelas
+++ exited (status 0) +++
我尝试过的所有其他shell都抱怨该未设置的HOME或将其/
用作默认home值。
还有一种不同的行为fish
,它似乎是在数据库中查询存储在其中的用户名($USER
如果有的话),或者getpwuid()
如果不是:
$ env -u HOME USER=bin ltrace -e getpw\* fish -c 'cd;pwd'
fish->getpwnam("bin") = 0x7fd2beba3d80
fish: Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory
where the current user has write access.
fish: Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory
where the current user has write access.
--- SIGCHLD (Child exited) ---
/bin
+++ exited (status 0) +++
$ env -u HOME -u USER ltrace -e getpw\* fish -c 'cd;pwd'
fish->getpwuid(1000, 0x7f529eb4fb28, 0x12d8790, 0x7f529e858697) = 0x7f529eb51dc0
fish->getpwnam("chazelas") = 0x7f529eb51d80
--- SIGCHLD (Child exited) ---
--- SIGCHLD (Child exited) ---
/home/chazelas
+++ exited (status 0) +++
用户不存在时的SEGV(https://github.com/fish-shell/fish-shell/issues/3599):
$ env -u HOME USER=foo fish -c ''
zsh: segmentation fault env -u HOME USER=foo fish -c ''