免责声明:使用 bash。
我只需要对我对这些事情的理解进行一些确认/纠正:
env
基本上显示我的当前会话和任何子会话(例如,如果我要bash
进入子会话)可以访问的当前环境变量。如果我要设置一个新变量,那么
MYMESSAGE="hello world!"
它只会对我创建它的会话可见。例如,如果我进入儿童会话,我将无法进行echo $MYMESSAGE
。我可以
export MYMESSAGE="hello world!"
让它可供儿童会话访问。与将其添加到拉起的export
任何内容相同。env
然而,仅仅因为你
export
做了某事,如果你碰巧关闭会话并重新启动终端,它就不会坚持下去。.bashrc
在您的目录中进行编辑/home/username/
并在其中添加任何新的环境变量,因为该脚本是在登录时运行的。
到目前为止我的理解正确吗?
此外,我不完全理解 的细节env
来自哪里。环境变量列表是否全部存储在某个文件中,然后由 编辑/附加.bashrc
?我只是想了解这一切是如何运作的。
答案1
你基本上是对的,但是还有一些额外的要点......
bash 可能会运行几个“启动文件” - 一些用于与 bourne-shell (sh) 向后兼容,其他则取决于您如何启动 bash: 您登录到 X 了吗?您是否登录了 TTY?您是否bash
从另一个(bash-)shell 开始? bash 是否作为脚本运行(非交互式)?因此 .bashrc 不是总是运行,也不能是唯一的启动文件。但是,最好也在其他启动文件中“获取”(读取并执行).bashrc,因此始终会添加 .bashrc 的内容。使用man bash
并查看有关 bash 如何启动的部分...FILES 部分还列出了 bash 使用的文件,包括所有启动文件。如需更深入的了解,请尝试info bash
.
除了您自己的启动文件之外,/etc 中还有相应的“默认”全局启动文件 - 这些文件通常在bash
您自己的启动文件之前读取/执行。除了 bash 定义的环境变量之外,还有其他程序定义了自己的环境变量,这可能会补充甚至覆盖 bash 设置的环境变量。特别值得注意的是 X(GUI),因为它将设置两个不同的环境集,具体取决于 X 是从 VT手动启动(使用xinit
或),还是由“显示管理器”(例如或)启动,以便您可以直接登录到 X(X 在您引导时启动,在 X) 中您会看到一个用于输入用户名/密码的对话框。startx
xdm
kdm
但在 或任何其他程序启动之前bash
,X
您将使用的大部分环境(环境变量)都已设置,例如通过命令设置login
。其中大部分内容可以在 /etc/login.defs 和其他配置文件中找到。例如,将设置 PATH 变量 - 并将根据您是 root 用户还是普通用户而有所不同。
因此,如果您查看作为引导、初始化和登录过程的一部分运行的各种文件和脚本;您会发现大部分可以用 列出的变量env
。然而,有些 - 例如CWD
(当前工作目录) - 由 shell (bash) 本身自动设置(和更新)。
当您运行命令时,bash 使用名为 fork() 的系统调用。 bash
基本上制作了自己的相同副本,除了子进程获得一个新的 PID(进程 ID)并且它的 PPID(父 PID)是它的“母亲”的 PPID(父 PID)。否则它们是相同的 - 甚至包括环境变量......假设有问题的变量是通过首先export
ing 使其可继承的。您现在拥有两份bash
.然后使用另一个系统调用 -exec() - ,它基本上用另一个程序替换子 bash 进程“内存中”的 bash 程序 - 例如使用ls
,ps
或mutt
(无论你输入什么)...但是环境变量仍然存在,因此新程序继承了它的环境bash
。这个孩子现在控制你的终端(除非你用 & 将命令放在后台)直到它终止,而你原来的 bash-shell (基本上)处于休眠状态。当命令终止时,您将返回到原始的bash
-shell,该 shell 已准备好执行另一个命令。
答案2
环境不是通过文件传递,而是通过新创建的进程的堆栈传递,实现此目的的方法是将环境传递给系统exec()
调用。
env
是一个外部命令(与 shell 内置命令相反),因此,仅打印来自 shellenv
的变量。exported
set
另一侧列出了所有 shell 变量。其中一些是出口的。export
列出 shell 导出的 shell 变量。
顺便提一句:
.bashrc
不是由登录 shell 运行,而是由每个交互式 (bash) shell 运行。其他 shell 对此功能有其他名称。ksh
使用.kshrc
和 Bourne Shell 使用.shrc
..profile
由登录 shell 运行。该文件在所有 Bourne Shell 兼容 shelle 之间共享。
答案3
你的理解是正确的。
您的 /home/username/.bashrc 附加(或覆盖) /etc/bash.bashrc 中的设置
/etc/profile 中还有一些相关设置,您可以拥有 /home/username/.profile,但这些设置主要是出于历史兼容性原因而存在。 (它们是 Bourne shell 的产物,Bash 是基于 Bourne shell 的。)