web*_*oon 22 linux environment-variables
我正在寻找 $HOME 环境变量设置的地方。在我看来,这是登录后。
我使用的是 Linux debian 2.6.32-5-686。
use*_*686 27
在 Linux 上,HOME环境变量由登录程序设置:
login控制台、telnet和rlogin会话sshdSSH 连接gdm,kdm或xdm用于图形会话。登录程序根据 /etc/passwd 中的值在 shell 上调用 exec 之前对其进行安排(通过将其包含在 exec 的参数中)。
如何更改: 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
通过运行编辑它: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 会尝试填充它,即使不在登录或交互模式下也是如此。