$HOME 环境变量在哪里设置?

web*_*oon 22 linux environment-variables

我正在寻找 $HOME 环境变量设置的地方。在我看来,这是登录后。

我使用的是 Linux debian 2.6.32-5-686。

use*_*686 27

在 Linux 上,HOME环境变量由登录程序设置:

  • 通过login控制台、telnetrlogin会话
  • 通过sshdSSH 连接
  • by gdmkdmxdm用于图形会话。


bma*_*ies 8

登录程序根据 /etc/passwd 中的值在 shell 上调用 exec 之前对其进行安排(通过将其包含在 exec 的参数中)。

  • 有趣的是,这并没有获得更多选票。这是实际指定环境变量设置位置的唯一答案,这是OP的实际问题。 (2认同)

use*_*871 6

如何更改: https: //superuser.com/a/694428/76871

(它在 中定义/etc/passwd;用 编辑它usermod -d /some/new/home/dir myusername,尽管修改文件可能有效)


当主目录写入 $HOME 环境变量时: https://superuser.com/a/271935/76871 https://superuser.com/a/271927/76871

(该字符串作为参数传递给登录程序,稍后将设置 $HOME 环境变量)


旁注:当 $HOME 变量未定义时,bash shell 将从其官方定义中获取它/etc/passwd并在该脚本中定义它。这可能表明您的脚本或编程语言可能对 $HOME 变量有特殊处理,因为它稍微“重要”(尽管可能不如 $PATH)。

https://superuser.com/a/1502106/76871

  • 您可能会将“$HOME”与“$PATH”混淆。在“$HOME”中拥有多个路径(整个值将被视为单个路径名)或者在大多数情况下根本修改“$HOME”是没有意义的。 (2认同)

Syn*_*ead 6

通过运行编辑它:usermod -d /home/whatever_dir whatever_user.

请注意,这(显然)将成为新的主目录。Bash 会cd在登录时使用它,因此请确保它存在且权限正确。另外,不要忘了.bashrc.profile.xinitrc等; 如果它们不在主目录中,则不会读取它们。

来自usermod

Usage: usermod [options] LOGIN

Options:
  -c, --comment COMMENT         new value of the GECOS field
  -d, --home HOME_DIR           new home directory for the user account
  -e, --expiredate EXPIRE_DATE  set account expiration date to EXPIRE_DATE
  -f, --inactive INACTIVE       set password inactive after expiration
                                to INACTIVE
  -g, --gid GROUP               force use GROUP as new primary group
  -G, --groups GROUPS           new list of supplementary GROUPS
  -a, --append                  append the user to the supplemental GROUPS
                                mentioned by the -G option without removing
                                him/her from other groups
  -h, --help                    display this help message and exit
  -l, --login NEW_LOGIN         new value of the login name
  -L, --lock                    lock the user account
  -m, --move-home               move contents of the home directory to the
                                new location (use only with -d)
  -o, --non-unique              allow using duplicate (non-unique) UID
  -p, --password PASSWORD       use encrypted password for the new password
  -R, --root CHROOT_DIR         directory to chroot into
  -s, --shell SHELL             new login shell for the user account
  -u, --uid UID                 new UID for the user account
  -U, --unlock                  unlock the user account
Run Code Online (Sandbox Code Playgroud)


小智 5

我做了一些挖掘,这个答案有点令人惊讶。采取以下测试脚本chmod +x

#!/bin/bash 
printf 'My home is: '
echo  ~ || echo 'nowhere'
Run Code Online (Sandbox Code Playgroud)

我们可以运行它并./test.sh查看:

我的家是:/home/user

让我们来看看 strace 的底层原理。

$ strace ./test.sh |& grep '^open[a-z]*'

openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = 3
openat( AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/dev/tty", O_RDWR|O_NONBLOCK) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/ lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
openat(AT_FDCWD, "./test.sh", O_RDONLY) = 3

我没有看到任何提及 HOME、rc 文件或 passwd 的内容。让我们在干净的环境中尝试一下:

env -i bash
echo $HOME  #this will be blank since we cleared the env
Run Code Online (Sandbox Code Playgroud)

不出所料,什么也没有。让我们在空白环境中运行脚本。

env -i bash
./test.sh 
Run Code Online (Sandbox Code Playgroud)

我的家是:/home/user

有趣的是,脚本能够回家。现在我们来追踪一下。

strace ./test.sh |& grep '^open[a-z]*'
Run Code Online (Sandbox Code Playgroud)

现在我们看到:

openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = 3
openat( AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/dev/tty", O_RDWR|O_NONBLOCK) = 3
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.缓存", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_compat.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.cache" , O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_nis.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnsl. so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/passwd", O_RDONLY |O_CLOEXEC) = 3
openat(AT_FDCWD, "./test.sh", O_RDONLY) = 3

我把有趣的线条加粗了。正如我们所看到的,当$HOME未定义时,shell 会尝试填充它,即使不在登录或交互模式下也是如此。