2015 12 01 shell path env - hanyong/note GitHub Wiki
分析各场景下涉及的配置文件和最终 PATH 变量值:
-
sudo -u admin -i
会重置初始 PATH 为 /etc/sudoers 指定值.
$ sudo strace -e open sudo -u admin -i
... ...
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 5
open("/etc/sudoers", O_RDONLY) = 5
open("/etc/sudoers.d/README", O_RDONLY) = 6
... ...
open("/etc/group", O_RDONLY|O_CLOEXEC) = 4
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 5
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 7
open("/etc/security/pam_env.conf", O_RDONLY) = 7
open("/etc/environment", O_RDONLY) = 7
open("/etc/security/pam_env.conf", O_RDONLY) = 7
open("/etc/default/locale", O_RDONLY) = 7
open("/etc/krb5.conf", O_RDONLY) = 7
open("/dev/urandom", O_RDONLY) = 7
open("/dev/urandom", O_RDONLY) = 7
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 7
open("/etc/security/capability.conf", O_RDONLY) = 7
open("/etc/login.defs", O_RDONLY) = 7
open("/etc/login.defs", O_RDONLY) = 7
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 7
open("/etc/group", O_RDONLY|O_CLOEXEC) = 7
open("/etc/krb5.conf", O_RDONLY) = 7
open("/dev/urandom", O_RDONLY) = 7
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 7
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 7
... ...
$ echo $PATH
/opt/apache-maven-3.2.3/bin:/opt/jdk1.8.0_65/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/admin/usr/local/bin
-
su admin -l
,/etc/login.defs
的 PATH 配置会覆盖/etc/environment
的配置
$ sudo strace -e open sudo su admin -l
... ...
open("/etc/group", O_RDONLY|O_CLOEXEC) = 4
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 5
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 7
open("/etc/security/pam_env.conf", O_RDONLY) = 7
open("/etc/environment", O_RDONLY) = 7
open("/etc/security/pam_env.conf", O_RDONLY) = 7
open("/etc/default/locale", O_RDONLY) = 7
open("/etc/krb5.conf", O_RDONLY) = 7
open("/dev/urandom", O_RDONLY) = 7
open("/dev/urandom", O_RDONLY) = 7
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 7
open("/etc/security/capability.conf", O_RDONLY) = 7
open("/etc/login.defs", O_RDONLY) = 7
open("/etc/login.defs", O_RDONLY) = 7
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 7
... ...
$ echo $PATH
/opt/apache-maven-3.2.3/bin:/opt/jdk1.8.0_65/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/admin/usr/local/bin
- ssh 登录, 生效的 PATH 来自
/etc/environment
, 但好像两个文件都没有读.
Tue Dec 1 11:31:42 2015 CST open "/etc/profile", O_RDONLY
Tue Dec 1 11:31:42 2015 CST open "/etc/bash.bashrc", O_RDONLY
... ...
Tue Dec 1 11:31:42 2015 CST open "/etc/profile.d/bash_completion.sh", O_RDONLY
... ...
Tue Dec 1 11:31:42 2015 CST open "/etc/profile.d/local.sh", O_RDONLY
Tue Dec 1 11:31:42 2015 CST open "/home/hanyong/.bash_profile", O_RDONLY
Tue Dec 1 11:31:42 2015 CST open "/home/hanyong/.bash_login", O_RDONLY
Tue Dec 1 11:31:42 2015 CST open "/home/hanyong/.profile", O_RDONLY
Tue Dec 1 11:31:42 2015 CST open "/home/hanyong/.bashrc", O_RDONLY
Tue Dec 1 11:31:42 2015 CST open "/home/hanyong/.bash_history", O_RDONLY
... ...
Tue Dec 1 11:31:42 2015 CST open "/home/hanyong/.inputrc", O_RDONLY
Tue Dec 1 11:31:42 2015 CST open "/etc/inputrc", O_RDONLY
- 直接控制台登录 (本机登录), 先读
/etc/login.defs
, 再读/etc/environment
, 后者生效.
Tue Dec 1 12:00:56 2015 CST open "/etc/passwd", O_RDONLY|O_CLOEXEC
Tue Dec 1 12:00:56 2015 CST open "/etc/shadow", O_RDONLY|O_CLOEXEC
Tue Dec 1 12:00:56 2015 CST open "/etc/security/capability.conf", O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/passwd", O_RDONLY|O_CLOEXEC
Tue Dec 1 12:00:56 2015 CST open "/etc/login.defs", O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/passwd", O_RDONLY|O_CLOEXEC
Tue Dec 1 12:00:56 2015 CST open "/etc/shadow", O_RDONLY|O_CLOEXEC
Tue Dec 1 12:00:56 2015 CST open "/etc/passwd", O_RDONLY|O_CLOEXEC
Tue Dec 1 12:00:56 2015 CST open "/etc/security/pam_env.conf", O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/environment", O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/security/pam_env.conf", O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/default/locale", O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/passwd", O_RDONLY|O_CLOEXEC
Tue Dec 1 12:00:56 2015 CST open "/proc/1/limits", O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/security/limits.conf", O_RDONLY
... ...
Tue Dec 1 12:00:56 2015 CST open "/etc/passwd", O_RDONLY|O_CLOEXEC
Tue Dec 1 12:00:56 2015 CST open 00007ffc9286a368, O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/profile", O_RDONLY
Tue Dec 1 12:00:56 2015 CST open "/etc/bash.bashrc", O_RDONLY
现象:
- 如果在登录相关脚本如
.profile
,.bashrc
设置了环境变量, 登录和非登录会产生不一样的环境. -
su -l
和直接登录的初始 PATH 是不一样的,su -l
取的是login.defs
. - sudo 直接重置初始 PATH. sudo 默认要带上
-H
(或使用-i
才) 会重置 HOME, 由配置env_reset
控制.
最佳实践:
- 登录相关脚本如
/etc/profile
,/etc/profile.d/*
,.profile
应该只包含优化交互体验的配置, 不包含其他配置. - 环境变量包括 PATH 统一配置在
/etc/environment
维护, 注意这个文件是简单环境变量语法, 不支持 shell 语法如 "PATH=$PATH:/xx/bin" 等. - sudo 属于临时提权, 只能执行 sudo 指定的标准 PATH 下的命令.
- 以用户身份执行用户 PATH 下的命令可使用
sudo su <login> -c
. - 不能配置单个用户自定义的 PATH, 如果配置在
.profile
, 则需要sudo su <login> -l -c
, 此时初始 PATH 变为login.defs
配置, 不推荐. 除非不修改默认初始 PATH 或者login.defs
和/etc/environment
的配置要同步, 不推荐.