Як оболонка знає будинки?


25

Кожна оболонка має набір змінної середовища $ HOME (наприклад: /Users/lotolo . Якщо я перебуваю під csh, я можу unsetenv HOMEі все-таки, якщо це зробити, cdбуду вдома. Я тестував це також на bash ( unset HOME), і це та ж поведінка. Тож як оболонка знає, де знаходиться мій / other_user дім? Де він читає ці значення?

Це не дублікат , так як моє запитання не як я знаю, але як в оболонці ноуHOME . І така поведінка поширюється і на інших користувачів.


1
@StephenKitt, не дублікат. Тут ми говоримо про поведінку оболонки для домашнього каталогу поточного користувача.
Стефан Хазелас

У простому випадку від /etc/passwd. Деякі системи можуть зберігати цю інформацію на LDAP, NIS-серверах тощо
Satō Katsura

1
Програми (включаючи оболонки) просто дзвонять getpwuid(3)або подібні. Деякі системи можуть бути налаштовані на "повторний маршрут" getpwuid(3)для отримання інформації з /etc/passwd, LDAP, NIS, NIS + тощо
Satō Katsura

@StephenKitt, дивіться мою відповідь
Stéphane Chazelas

1
@ GAD3R, див. Дискусію вище, StephenKitt вже вказував на той самий дублікат (який він з моменту відкликання), але я стверджую вище (і див. Також мою відповідь), що це не дублікат.
Стефан Хазелас

Відповіді:


33

У випадку 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, що, схоже, запитує базу даних для ім'я користувача, яке зберігається, $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/isissue/3599 ):

$ env -u HOME USER=foo fish -c ''
zsh: segmentation fault  env -u HOME USER=foo fish -c ''

2
Я думаю, ми можемо повідомити про це питання! Дуже приємна відповідь btw, дякую!
LotoLo

1
@LotoLo, так, я зайнятий будівництвом з fishdev git head, щоб побачити, чи є помилка також. Редагувати. Так.
Стефан Хазелас

Зараз мені цікаво: яка змінна середовище робить оболонку максимально непривітною для користувачів, якщо її не встановлено? PATH? TERM? USER?
user1024

Тут є незвичайний рядок: "було б лише наближенням ..." В цьому абзаці теж не містяться дужки. Що це повинно було бути?
muru

1
@muru Querying the user database... would only be...не так зрозуміло насправді
edc65

6

Тож як оболонка знає, де знаходиться мій / other_user дім?

Це не так. Ви просто не виконуєте експеримент належним чином. Як видно з посібника з оболонкою C, cdкоманда змінює значення homeзмінної, якщо вона постачається без аргументів. Якщо цю змінну не встановлено, вона не знає, куди потрібно змінити каталог і надрукує помилку:

машина: ~> встановити дім = /
машина: / home / user> cd
машина: ~> вимкнути дім
машина: /> cd
CD: Немає домашнього каталогу
машина: /> 

Ви скасуєте неправильну змінну. Це не HOMEзмінна середовище, це homeвнутрішня змінна оболонки C (ініціалізована зі значення колишньої при запуску оболонки, але в іншому випадку незалежна змінна сама по собі).


ні на csh (принаймні, у моїй версії: "tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-apple-darwin)") це HOME-змінна, що несе домашнє значення. Але як сказав @Stephane Chazelas, я повинен зняти змінну перед запуском оболонки, оскільки вона встановить значення HOME при запуску.
LotoLo

Наведене вище - оболонка C, яку я запустив на зручній машині OpenBSD, і демонструє її поведінку. Це навіть не оболонка TENEX C (хоча вона і так поводиться).
JdeBP

Так, я це бачив ... Я набрав, cshале, мабуть, це tcsh
відчужено

0

Система встановила змінну HOME під час входу в систему, щоб бути іменем шляху домашнього каталогу користувача. Його встановлює

  • gdm, kdm або xdm для графічних сеансів.
  • увійти на консолі, telnet та rlogin сесії
  • sshd для SSH-з'єднань

Ви можете змінити його значення, але зверніть увагу, тому що .bashrc, .profile, .xinitrc тощо не будуть прочитані, якщо їх немає в домашньому каталозі.


Але я можу зняти його ($ HOME) ... правда? І як дізнатися, де знаходиться будинок іншого користувача?
LotoLo

1
ви можете оновити його за допомогою usermod -d HOME_DIRкоманди, коли буде створено новий usre. home default є / home / $ username, і це визначається програмою входу.
Дабабі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.