貝殼如何知道家?
每個 shell 都有一個環境變數 $HOME 集(例如:)
/Users/lotolo
。如果我在 csh 之下,我可以unsetenv HOME
,如果我這樣做,cd
我仍然會在我的家中。我也在 bash (unset HOME
) 上對此進行了測試,這是相同的行為。那麼 shell 是如何知道 my/other_user 的家在哪裡呢?它在哪裡讀取這些值?這不是重複的,因為我的問題不是我怎麼知道,而是shell怎麼知道
HOME
。這種行為也擴展到其他使用者。
在 and 的情況下
csh
,tcsh
它記錄了$HOME
shell 啟動時變數的值(在其$home
變數中,如 @JdeBP 所述)。如果您在開始之前取消設置
csh
,您會看到如下內容:$ (unset HOME; csh -c cd) cd: No home directory.
對於
bash
(以及大多數其他類似 Bourne 的 shell),我看到的行為與您的不同。bash-4.4$ unset HOME; cd bash: cd: HOME not set
變數的內容
$HOME
由登錄過程根據儲存在使用者數據庫中的資訊與您的使用者名進行初始化。關於使用者名本身的資訊並不總是可用的。所有 shell 可以確定的是正在執行它的程序的使用者 ID,並且多個使用者(具有不同的主目錄)可以共享相同的使用者 ID。
因此,一旦
$HOME
消失,就沒有可靠的方法可以將其取回。查詢使用者數據庫(使用
getpwxxx()
標準 API)以獲取與執行 shell 的使用者具有相同 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
‘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 ''