我对设置的文件感到困惑默认值 PATH
在 Linux(特别是 Debian)上。 (我对~
(.profile
, ,也许其他)中的用户特定的不感兴趣xsessionrc
。)
到目前为止,我已经排除了(不那么)常见的嫌疑/etc/{environment,bash.bashrc,login.defs,profile,crontab,security/pam_env.conf,default/locale,default/cron,pam.d/sshd,pam.d/cron}
,但每次登录时/usr/sbin/sshd
我的默认值仍然PATH
设置为“/local/games” ,结果什么也没有。我怀疑它被硬编码在某个地方的二进制文件中。我在用着/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
/etc
bash
答案1
简而言之,经验规则标准用户,在 Debian 11 上
/etc/profile
,设置权威PATH;/etc/environment
或者/etc/default/locale
;/usr/local/bin:/usr/bin:/bin:/usr/games
(如果是 GDM、XDM... 或 OpenSSH);/etc/login.defs
'ENV_PATH
选项(如果是控制台);- 回退到
getconf PATH
-- 或 C 等效项(如果是控制台)。
如果是 GDM、XDM... 或 OpenSSH意思是:如果您的会话是图形桌面或 SSH。
如果控制台意思是:如果您的会话是控制台,即不在图形桌面或 SSH 中(见下文)。
这不适合su
也不适合sudo
环境。
下面,我们假设用户在每次测试之间注销/登录。
测试设置
VERSION="11 (bullseye)"
- 显示管理器:GDM3
- 桌面:侏儒, 终端:gnome 终端, 壳:巴什
删除用户的~/.bashrc
、~/.bash_profile
、~/.bash_login
和 后~/.profile
,命令printenv PATH
返回 : /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
。搜索该字符串会/etc
弹出/etc/profile
文件。
第一步:改变/etc/profile
并看看效果如何
注释掉/etc/profile
第 4-9 行(路径操作部分)后,
printenv PATH
然后说:/usr/local/bin:/usr/bin:/bin:/usr/games
。 PATH 中缺少/usr/local/games
表明该操作对系统产生了影响,太好了!
下一步:/usr/games
尽可能寻找字符串
事情变得有点棘手,你需要安装源码包xdm
,,,, 。然后查找显示其中三个(、、 )在文件中设置了某种类型。gdm3
lightdm
openssh
/usr/games
xdm
gdm3
openssh
default_path
debian/rules
Gdm3 的代码指出,如果满足以下条件,则使用该值:pam_getenv(3)不返回 PATH 值。
lightdm案例:
这个略有不同,有一个debian/patches/01_set-default-path.patch
文件将源代码中的路径硬编码(而不是编译参数)。
警告:Debian 维护者使用的完全相同的 PATH 序列比/etc/profile
(/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
)。在这种情况下,通过注释代码更难注意到更改。
下一步:看/etc/pam.d
政策
该文件/etc/pam.d/gdm-launch-environment
似乎是一个不错的候选者。它来源两个文件:
/etc/environment
;/etc/default/locale
(您不应该在此处放置 PATH 声明 ^^)。
长话短说,我们没有检查所有可能的行为,但 GDM 和 OpenSSH 的行为相同,所以你可以打赌这是 Debian 的方式:
- 如果
/etc/profile
没有设置PATH- 如果你设置了一个
PATH=/somepath
条目/etc/environment
- 应用此条目,
- 别的
- 使用已编译的后备 (
/usr/local/bin:/usr/bin:/bin:/usr/games
)
- 使用已编译的后备 (
- 如果你设置了一个
再脱一点
因此,OpenSSH 和 DM 会覆盖空PATH
变量,但控制台不使用它们。事实证明,当/etc/profile
的 PATH 部分被注释并且/etc/environment
文件为空(默认状态)时,将使用第三个 PATH 值:/etc/login.defs
ENV_PATH 选项。
您可以注释/etc/login.defs
第 103 行以获得类似以下内容:
$ grep -nE '^#?ENV_(SU)?PATH' /etc/login.defs
102:ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
103:#ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
然后您可以登录控制台(串行和 TTY应该行为相同)并printenv PATH
再次玩。这次应该显示:/bin:/usr/bin
。这等于getconf PATH
我的系统上的值,所以我认为我们已经到达底部了。
其他(也许)有趣的点
请注意,OpenSSH 和图形显示会话休息环境变量继承(cf环境(7))。
答案2
Linux 系统中有很多地方PATH
可以设置或更新变量。这取决于访问系统的模式和所涉及的软件(sshd
例如,SSH 守护程序 包含 的硬编码值PATH
)。我不知道您在系统上看到的值是在哪里设置的。因此,在这个答案中,我将解决您在问题末尾提到的怀疑。
可执行bash
文件包含变量的默认值PATH
。
bash
从源码编译shell时,可以修改该文件config-top.h
。该文件包含各种编译时设置,这些设置通常由系统分发者(程序包维护者)更改,以符合其操作系统发行版的风格。
该文件设置的内容之一是DEFAULT_PATH_VALUE
宏的值。 shell 的分布式源中设置的值是字符串
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.
这将是命令输出的内容
env -i bash -c 'echo "$PATH"'
PATH
这将从不从父 shell 继承任何环境变量且不获取任何 shell 初始化文件的 shell 中输出变量的值。