哪些文件设置默认 PATH

哪些文件设置默认 PATH

我对设置的文件感到困惑默认值 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/etcbash

答案1

简而言之,经验规则标准用户,在 Debian 11 上

  1. /etc/profile,设置权威PATH;
  2. /etc/environment或者/etc/default/locale;
  3. /usr/local/bin:/usr/bin:/bin:/usr/games(如果是 GDM、XDM... 或 OpenSSH);
  4. /etc/login.defs'ENV_PATH选项(如果是控制台);
  5. 回退到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,,,, 。然后查找显示其中三个(、、 )在文件中设置了某种类型。gdm3lightdmopenssh/usr/gamesxdmgdm3opensshdefault_pathdebian/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.defsENV_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 中输出变量的值。

相关内容