В случае csh
и tcsh
он записывает значение $HOME
переменной во время запуска оболочки ( в ее $home
переменной, как отмечено @JdeBP ).
Если вы отключите его перед запуском csh
, вы увидите что-то вроде:
$ (unset HOME; csh -c cd)
cd: No home directory.
Для bash
(и большинства других подобных Борну оболочек) я вижу поведение, отличное от вашего.
bash-4.4$ unset HOME; cd
bash: cd: HOME not set
Содержимое $HOME
переменной инициализируется процессом входа в систему на основе информации, хранящейся в базе данных пользователей, относительно вашего имени пользователя .
Информация о самом имени пользователя не всегда доступна. Оболочка может знать наверняка только идентификатор пользователя процесса, который ее выполняет, и несколько пользователей (с разными домашними каталогами) могут использовать один и тот же идентификатор пользователя.
Таким образом, после того, $HOME
как ушел, нет надежного способа вернуть его.
Запрос к базе данных пользователей (со getpwxxx()
стандартным API) для домашнего каталога первого пользователя, который имеет тот же uid, что и тот, в котором запущена оболочка, будет лишь приблизительным (не говоря уже о том, что база данных пользователей могла измениться (или домашний каталог). каталог определяется как одноразовое значение) с момента начала сеанса входа в систему).
zsh
единственная известная мне оболочка, которая делает это:
$ env -u HOME ltrace -e getpw\* zsh -c 'cd && pwd'
zsh->getpwuid(1000, 0x496feb, 114, 0x7f9599004697) = 0x7f95992fddc0
/home/chazelas
+++ exited (status 0) +++
Все остальные оболочки, которые я пробовал, либо жалуются на этот неустановленный HOME, либо используют /
в качестве домашнего значения по умолчанию.
И все же другое поведение - это fish
's', который, кажется, запрашивает в базе данных имя пользователя, сохраненное, $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 ''