为什么 $SLVL 在非登录 shell 中从级别 2 开始,而在 RHEL 7 的登录 shell 中从级别 1 开始?

为什么 $SLVL 在非登录 shell 中从级别 2 开始,而在 RHEL 7 的登录 shell 中从级别 1 开始?

我正在使用“Red Hat Enterprise Linux Server 版本 7.1 (Maipo)”。当我处于非登录 shell 中时,shell 级别 ( $SHLVL) 从 2 开始,并随着连续的子 shell 的增加而增加。但是当我使用登录 shell 时,shell 级别从 1 开始,并随着连续的子 shell 的增加而增加。

问题:为什么登录 shell(从 1 开始)和非登录 shell(从 2 开始)之间的最低 shell 级别存在差异?

我在 GUI 终端中使用 bash。

[aditya@vulcan ~]$ echo $SHLVL
2
[aditya@vulcan ~]$ su -l aditya
Password:
Last login: Fri Jan 12 11:38:56 IST 2018 on :0
[aditya@vulcan ~]$ echo $SHLVL
1
[aditya@vulcan ~]$

答案1

当您登录到 GUI 会话时,设置会话的脚本将在非交互式登录 shell 中执行。它读取/etc/profile, your~/.[bash_]profile等并为整个 GUI 会话设置环境。然后 shell 执行一个脚本来启动您的桌面环境。有效地,您的会话的 shell 将为 SLVL 1。

X 会话设置脚本实际上可能是exec实际启动桌面环境的最后一个命令。这解释了为什么您无法在会话的进程树视图中找到 shell 进程 ( ps xf):该 shell 已完成其工作并消失,只有其环境变量(以及任何其他可继承的设置,如自定义 ulimit)被继承桌面环境的主进程,它将它们传递给其所有子进程。这样,从桌面菜单启动的程序也将具有您在 .bash_profile 中设置的任何环境变量,因此将按您的预期工作。

还可以将终端窗口设置为作为登录 shell 启动,因此它们将是 SLVL 1。至少 Debian 上的 KDE 似乎是这样做的。

答案2

从 bash 手册页:

SLVL 每次启动 bash 实例时加一。

正如你所看到的,这个变量与它是否是登录 shell 无关。这只是意味着您的 bash shell 已被另一个 bash shell 启动。由于我们不知道您到底在做什么来获取 shell,所以我不能说为什么您有嵌套的 shell 调用,但这里有一些常见情况:

  • 您正在从命令行启动一个新的终端窗口

  • 您正在使用某些操作系统功能来启动一个新的终端窗口,该功能是通过首先启动 bash 来实现的,然后运行终端,然后终端运行一个新的 shell

  • 你的 .bash_profile 中有一个递归bash调用,每当 SLVL 等于 1 时就会运行该调用(这听起来很奇怪,但我已经见过两次了!)

相关内容