KDE 的环境变量加载来源和顺序
systemd, SDDM, plasma 桌面,都会加载各种环境变量

systemd 环境变量

systemd 是 1 号进程,其它所有进程都会继承它的环境变量。

systemd 的环境变量由 systemd.environment-generator(7) 生成。存放在以下路径

  • /lib/systemd/system-environment-generators/*
  • /usr/lib/systemd/system-environment-generators/*
  • /usr/local/lib/systemd/system-environment-generators/*
  • /etc/systemd/system-environment-generators/*
  • /run/systemd/system-environment-generators/*

显然,/lib, /usr/lib 下的是系统或者软件包带的,/etc 下的是管理员配置的,/run 下的是临时生成的。

每个文件都是可执行文件(可以是 shell 脚本,也可以是 ELF executable),执行后向标准输出一行行 NAME=VALUE 格式的环境变量。例如:

#!/bin/sh

echo 'PATH=/usr/bin:/bin'

系统自带的配置会生成一些非常基础的环境变量。

systemd user 环境变量

  • /lib/systemd/user-environment-generators/*
  • /usr/lib/systemd/user-environment-generators/*
  • /usr/local/lib/systemd/user-environment-generators/*
  • /etc/systemd/user-environment-generators/*
  • /run/systemd/user-environment-generators/*

类似地,这个影响 systemd 用户会话的环境变量。用户进程都是从这里 fork 出来的,会进程这里的环境变量。

systemd-environment-d-generator

/usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator

这是一个特殊的 user environment generator, 它会加载来自 environment.d(7) 的配置。这些配置包括:

  • /etc/environment
  • /usr/lib/environment.d/*.conf
  • /etc/lib/environment.d/*.conf
  • /run/environment.d/*.conf
  • ~/.config/environment.d/*.conf

这里的文件就不是可执行文件了,而是传统的 /etc/environment 格式。例如:

LANG=en_US.UTF-8

SDDM

SDDM 是 KDE 的登录管理器,用户登录后,会运行 wayland-session 或 Xsession 脚本。

脚本的路径由 /etc/sddm.conf 中的 SessionCommand 指定,默认应该是 /usr/share/sddm/scripts/wayland-session/usr/share/sddm/scripts/Xsession.

脚本会先根据环境变量 SHELL 的值,去加载对应 shell 的 profile, 再 execve(2) 桌面环境的启动命令。

SHELL 代表的是用户的默认 shell, 由 systemd-logind 根据 /etc/passwd 中的值设置的,可以用 chsh 命令修改。

SDDM 的 session 脚本的实现很有意思。它们都是 #!/bin/sh 的 POSIX 脚本,直接去加载什么 zsh, fish 的 profile 肯定是不行的。所以它们会先根据 SHELL 的值,去 execve(2) 对应的 shell, 并且把自己收到的参数透传过去,用对应的 shell 把自己重新执行一遍。重新执行的时候,去 source 相关的 profile 就没有问题了。

由于这个 session 脚本的存在,我们在 login shell 的 profile 里(如 zsh 的 ~/.zprofile, bash 的 ~/.bash_profile export 的环境变量,就可以带到后面的 GUI 进程中。

备注:profile 和 rc 的区别

profile 由 login shell 执行,rc 由非 login shell 执行。由于环境变量是在父子进程间继承的,一般在 profile 里面 export 就可以了。而 alias 之类的 shell 配置,就必须在 rc 里面配置。

Plasma 桌面的 pre-startup 脚本

Pre-startup 脚本会在 plasma 桌面启动的早期阶段 source 进来,后面的进程都会继承这些的环境变量。这些脚本包括

  • /etc/xdg/plasma-workspace/env/*.sh
  • ~/.config/plasma-workspace/env/*.sh

推荐在这里设置 GUI 相关的环境变量,比如 GTK_IM_MODULE, QT_IM_MODULE, GDK_DPI_SCALE.

参考资料


最后修改于 2021-10-21