Как оболочка знает дома (дома)?

Каждая оболочка имеет переменную среды $ HOME (ex: /Users/lotolo ). Если я под csh, я могу unsetenv HOME и если я сделаю cd я буду в своем доме. Я тестировал это также на bash ( unset HOME ), и это то же поведение. Итак, как оболочка знает, где мой / other_user дома? Где он читает эти значения?

Это не дубликат, поскольку мой вопрос не в том, как я знаю, но как оболочка знает HOME . И это поведение распространяется и на других пользователей.

  • Вопросы по завершению tcsh
  • tcsh: введите 2-значные часы в строке
  • tcsh отображает курсор на следующей строке
  • Неоднозначно называемые исполняемые файлы
  • Выражение Grep со специальными именами файлов
  • Почему мой $ PATH не наследуется вызванным bash?
  • Синтаксис декларации оболочки оболочки Shell, () vs {}
  • Как временно обходить псевдоним в tcsh?
  • 3 Solutions collect form web for “Как оболочка знает дома (дома)?”

    В случае 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 инициализируется процессом входа в систему на основе информации, хранящейся в базе данных пользователя, против вашего имени пользователя.

    Информация о самом имени пользователя не всегда доступна. Вся оболочка может точно знать, является ли пользователь процессом процесса, выполняющим его, и несколько пользователей (с разными домашними каталогами) могут совместно использовать один и тот же идентификатор пользователя.

    Итак, как только $HOME ушел, нет надежного способа вернуть его.

    Запрос пользовательской базы данных (с стандартным API-интерфейсом getpwxxx() ) для домашнего каталога первого пользователя, который имеет тот же самый uid, что и тот, который работает с оболочкой, будет только приблизительным (не говоря уже о том, что пользовательская база данных могла быть изменена ( или домашний каталог определяется как одноразовое значение) с момента запуска сеанса входа в систему.

    zsh – единственная оболочка, которую я знаю, которая делает это:

     $ env -u HOME ltrace -e getpw\* zsh -c 'cd && pwd' zsh->getpwuid(1000, 0x496feb, 114, 0x7f9599004697) = 0x7f95992fddc0 /home/chazelas +++ exited (status 0) +++ 

    Все остальные оболочки, которые я попробовал, либо жалуются на этот unset 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 '' 

    Итак, как оболочка знает, где мой / other_user дома?

    Это не так. Вы просто не выполняете эксперимент должным образом. Как вы можете видеть из руководства оболочки C, команда cd изменяет значение home переменной, если она не содержит аргументов. Если эта переменная не установлена, она не знает, где сменить каталог и распечатать ошибку:

      машина: ~> set home = /
     machine: / home / user> cd
     машина: ~> неустановленный дом
     машина: /> cd
     cd: нет домашнего каталога
     Машина: /> 

    Вы устанавливаете неправильную переменную. Это не HOME , переменная среды, она содержит внутреннюю переменную C shell (инициализированную значением первого, когда запускается оболочка, но в остальном независимая переменная сама по себе).

    Система устанавливает переменную HOME во время входа в систему как путь к домашнему каталогу пользователя. Он устанавливается

    • gdm, kdm или xdm для графических сеансов.
    • логин на консоли, сеансы telnet и rlogin
    • sshd для SSH-соединений

    Вы можете изменить его значение, но обратите внимание, потому что .bashrc, .profile, .xinitrc и т. Д. Не будут прочитаны, если они не находятся в домашнем каталоге.

    Linux и Unix - лучшая ОС в мире.