シェルはどのように家を知っていますか?


25

各シェルには、環境変数$ HOMEが設定されています(例:)/Users/lotolo。私がcshの下にいる場合、私はできますがunsetenv HOME、それでも私は家cdにいます。これもbash(unset HOME)でテストしましたが、同じ動作です。では、シェルはどのようにしてmy / other_userの家がどこにあるのかを知るのでしょうか?それらの値はどこで読み取られますか?

私の質問は私がどのよう知っているのではなく、シェルがどのよう知っているので、これは重複していませんHOME。また、この動作は他のユーザーにも拡張されています。


1
@StephenKitt、複製ではない。ここでは、現在のユーザーのホームディレクトリのシェルの動作について説明しています。
ステファンシャゼラス

からの単純な場合/etc/passwd。一部のシステムでは、など、LDAPにNISサーバを、その情報を格納することができます
佐藤桂

1
プログラム(シェルを含む)は、単に呼び出すgetpwuid(3)か類似しています。いくつかのシステム「再ルーティング」に設定することができますgetpwuid(3)から情報を取得するには/etc/passwd、LDAP、NIS、NIS +など
佐藤桂

@StephenKitt、私の答えを参照してください
ステファンシャゼル

1
@ GAD3R、上記の議論を参照してください、StephenKittはすでに同じ複製を指していました(彼はその後撤回しました)が、私はそれが複製ではないと主張します(そして私の答えも参照してください)。
ステファンシャゼラス

回答:


33

以下の場合cshtcsh、それがの値を記録$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 ''

2
この問題を報告できると思います!ところで、とてもいい答えです、ありがとう!
LotoLo

1
@LotoLo、はいfish。編集。はい、そうです。
ステファンシャゼラス

今、私は興味があります:設定されていない場合、どの環境変数がシェルを最大限にユーザーフレンドリーにしますか? PATHTERMUSER
user1024

ここには奇妙な線があります:「近似値にすぎません...」括弧もその段落に並んでいません。それはどうなっているのでしょうか?
ムル

1
@muru Querying the user database... would only be...そう確かにクリアしていない
edc65

6

では、シェルはどのようにしてmy / other_userの家がどこにあるかを知るのでしょうか?

そうではありません。実験を適切に実行していないだけです。Cシェルのマニュアルからわかるように、引数なしでcdコマンドを指定すると、コマンドはhome変数の値に変わります。この変数が設定されていない場合、ディレクトリの変更先がわからず、エラーが出力されます。

machine:〜> home = /を設定します
machine:/ home / user> cd
マシン:〜>家の設定解除
machine:/> cd
cd:ホームディレクトリなし
マシン:/> 

間違った変数の設定を解除します。これはHOME、環境変数ではなくhome、Cシェルの内部変数です(シェルの起動時に前者の値から初期化されますが、それ以外の場合は独自の独立変数です)。


cshにはありません(少なくとも私のバージョンでは: "tcsh 6.18.01(Astron)2012-02-14(x86_64-apple-darwin)")それはhomeの値を運ぶHOME変数です。しかし、@ Stephane Chazelasが言ったように、シェルを起動する前に変数の設定を解除する必要があるため、起動時にHOME値が設定されます。
LotoLo

上記 Cシェルで、便利なOpenBSDマシンで実行し、その動作を示しています。TENEX Cシェルでさえありません(同じように動作しますが)。
JdeBP

はい、私はそれを見ました...私はタイプしましたcshが、どうやらそれはtcsh
LotoLo

0

システムは、ログイン時にHOME変数をユーザーのホームディレクトリのパス名に設定しました。によって設定されます

  • グラフィカルセッション用のgdm、kdmまたはxdm。
  • コンソール、telnetおよびrloginセッションにログイン
  • SSH接続のsshd

値を変更できますが、ホームディレクトリにない場合は.bashrc、.profile、.xinitrcなどが読み込まれないため、注意が必要です。


ただし、設定を解除できます($ HOME)... そして、他のユーザーの家がどこにあるのかをどのようにして知るのでしょうか?
ロトロ

1
usermod -d HOME_DIR新しいusreが作成されたら、コマンドを使用して更新できます。デフォルトのホームは/ home / $ usernameであり、ログインプログラムによって決定されます。
ダバビ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.