问题描述
我正在尝试 integrate RVM with gnome-terminal 。
默认情况下,gnome-terminal 不会将 bash 作为登录 shell 启动。我按照 this answer 中关于设置 RVM 的相同主题的建议启用了 run command as a login shell
,但是当我这样做时,不会读取 .bashrc
文件。
例如,我在 .bashrc
中创建了一个环境变量,然后当我启动一个新的 gnome-terminal 时,我无法读取它。我需要显式运行 source .bashrc
来读取文件。
这是预期的行为吗?
最佳方案
是的,这是预期的行为。
简而言之,行为如下:
-
bash 以交互式登录 shell 开始:读取
~/.profile
-
bash 以交互式非登录 shell 开始:读取
~/.bashrc
阅读 bash manual about startup files 了解更多详情。
就个人而言,我认为这种行为很奇怪,我还没有找到这个设计决策的合理性。
术语的一些解释:
-
交互式 shell 是您可以与之交互的 shell ,这意味着您可以在其中键入命令。您将使用的大多数 shell 都是交互式 shell。
-
非交互式 shell 是您无法与之交互的 shell。 Shell 脚本在非交互式 shell 中运行。
-
登录 shell 是在您登录系统时启动的 shell。
-
非登录 shell 是在登录过程之后启动的 shell。
您看到的大多数 shell 都是交互式非登录 shell。如果您正在运行像 gnome 这样的图形环境,则尤其如此,因为 gnome 是 “login shell”。在 gnome 中启动的任何 bash 会话都是非登录 shell。如果您想查看真正的交互式登录 shell,请转到虚拟控制台(使用 Ctrl+Alt+F1
),然后使用您的用户名和密码登录。那是一个真正的交互式登录 bash shell。您可以使用 Ctrl+Alt+F7
返回图形 shell。
有一个选项 --login
将使 bash 表现得好像它是一个登录 shell,即使在您登录后启动也是如此。配置 gnome-terminal 以将 bash 作为登录 shell 启动意味着它将使用 --login
选项启动 bash。
通常您希望 bash 在交互式 shell 中始终读取 ~/.bashrc
。我建议这样做:
创建一个 ~/.bash_profile
文件。如果 bash 作为登录 shell 启动,它将首先查找 ~/.bash_profile
,然后再查找 ~/.profile
。如果 bash 找到 ~/.bash_profile
那么它不会读取 ~/.profile
。
将以下行放入 ~/.bash_profile
:
[ -f "$HOME/.profile" ] && source "$HOME/.profile"
[ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc"
现在,如果 bash 作为交互式登录 shell 启动,它将读取以下文件:
-
~/.bash_profile
-
~/.profile
-
~/.bashrc
如果 bash 作为交互式非登录 shell 启动:
-
~/.bashrc
您应该将特定于 bash 的东西放在 ~/.bashrc
中,将非 bash 特定的东西放在 ~/.profile
中。例如 PATH
进入 ~/.profile
和 HISTCONTROL
进入 ~/.bashrc
。
请注意,~/.profile
不是 bash 特定的。其他基于文本的 shell(例如 sh 或 ksh)和图形 shell(gnome)也读取 ~/.profile
。这就是为什么您不应该将 bash 特定的东西放在 ~/.profile
中的原因。
次佳方案
这既不是一个糟糕的设计决策,也不是错误,也不是 shell 和终端的预期行为
它只是 Gnome 终端中 per-profile 配置选项的不幸默认值,您可以轻松修复它。
-
转到编辑->个人资料偏好。
-
选择标题和命令选项卡。
-
注意 Run command as login shell 复选框是如何被取消选中的!核实。
而已。如果您对 Default
配置文件或任何配置为在制作新终端时使用的配置文件执行此操作,您将获得一个登录 shell。
我猜在幕后,这个选项可能会导致它将 -l
选项传递给 shell。