以下の場合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
変数の内容は、ユーザー名に対してユーザーデータベースに保存されている情報に基づいて、ログインプロセスによって初期化されます。
ユーザー名自体に関する情報は常に利用できるとは限りません。シェルが確実に知ることができるのは、それを実行しているプロセスのユーザーIDだけであり、複数のユーザー(異なるホームディレクトリを持つ)が同じユーザーIDを共有できます。
そのため、一度$HOME
消えると、信頼できる方法はありません。
getpwxxx()
シェルを実行しているユーザーと同じuidを持つ最初のユーザーのホームディレクトリの(標準APIを使用した)ユーザーデータベースへのクエリは、概算にすぎません(ユーザーデータベースが変更された可能性があることは言うまでもありません(または、ホームログインセッションが開始されてから1回限りの値として定義されているディレクトリ)。
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
保存されているユーザー名をデータベースに照会する$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 ''