TGTGInsighttelegram intelligenceLIVE / telegram public index
← Hypercube's Channel
Hypercube's Channel avatar

TGINSIGHT POST

Post #47

@SmartHypercube_channel

Hypercube's Channel

Views154帖子阅读量
发布12月22日2021/12/22 13:18
Post content

帖子内容

今天升级了 Debian 11,顺便学习了一下怎么确保所有程序都拿到一些环境变量(如 locale 相关环境变量)。以下说明虽然并不完全精确,但或许会让理解相关概念简单一些。 环境变量应该在进程树中尽可能高的地方被设置一次,之后不要重复设置,一直从父进程继承。.profile 文件一般是用来做这件事的。在 sh 的时代,实现这个目标比较简单:如果 sh 发现自己是 login shell,说明用户刚刚登入,自己是这个用户的进程树中最高的进程,所以应该加载 .profile 文件。如果不是 login shell,则不加载。 在 bash 的时代,为了和 sh 保持一致,虽然可以有 .bash_profile,但 bash 也读属于 sh 的 .profile。因此无须专门创建 .bash_profile,用 .profile 即可。 但是 bash 还有另外一项功能,就是在每次启动时(如果是交互式)执行 .bashrc,以便设置一些无法从父进程继承的配置,例如 PS1 或 alias。不知由于什么原因,bash 被设计为如果读了 .profile,就不会读 .bashrc,虽然 .bashrc 的内容明明应该是每次交互式执行都需要的。为了解决这个问题,一般都在 .profile 中检查当前进程是不是 bash,如果是,就读 .bashrc,这样恰好修复了 bash 的这个问题。其他 shell 如果有类似问题,也应当这样修复。 这时,.profile 和 .bashrc 的区别就很明确了,前者应该存放环境变量等“只需设置一次,所有程序都要用”的信息,后者则仅仅是 bash 这一个软件内部的配置,和各种其他软件的 rc 文件类似。这样编写内容后,如果有软件不按这样的思想工作,应该设法修复。 例如,在桌面系统中,从图形界面登录后,会发现 .profile 没有被加载过,那就要设法让 display manager 程序(用户的进程树的顶端)加载 .profile。有的系统中相关软件被配置为会读取 .xprofile 文件,Debian 系统则规定一律使用 .xsessionrc 文件。因此对于我来说,在 .xsessionrc 文件中写上一行载入 .profile 的命令即可。 如果通过 ssh 连接远程机器,因为登录后启动的第一个进程会是 bash,所以它会作为 login shell 读取 .profile,没有问题。 如果把这些文件放进了 docker 中(虽然这样做有点奇怪👀),然后直接在 docker 中启动 bash,会发现 bash 并不读取 .profile,因为不是 login shell,这又违反了上面说的思想。可以通过以 root 身份执行 login -f username 解决,这会启动一个 login shell,确保读取 .profile。这还有额外的好处,login 会设置一些基础环境变量,例如 USER SHELL 等(不走这个流程的话默认是没有这些变量的),还会进入用户家目录,产生一个相当正常的环境。