配置 gnome-terminal 以启动 bash 作为登录 shell,不读取 .bashrc

配置 gnome-terminal 以启动 bash 作为登录 shell,不读取 .bashrc

我试图将 RVM 与 gnome-terminal 集成

默认情况下,gnome-terminal 不会将 bash 作为登录 shell 启动。我run command as a login shell按照建议启用了这个答案关于设置 RVM 的同一主题,但是当我这样做时,文件.bashrc不会被读取。

例如,我在 中创建了一个环境变量,.bashrc然后当我启动一个新的 gnome-terminal 时,我无法读取它。我需要明确运行source .bashrc才能读取该文件。

这是预期的行为吗?

答案1

是的,如果 gnome 终端配置为启动 bash 作为登录 shell,则 bash 将不会读取.bashrc

简而言之,该行为如下:

  • bash 最初是一个交互式登录shell:读取.profile但没有.bashrc
  • bash 最初是一个交互式非登录shell:读取.bashrc但没有.profile

(下面将详细说明这一点的更多特殊之处)

这一设计决策背后肯定有其合理性,在过去的某个时候,它还是有意义的。但现在,它只是一个让新来者感到困惑的烦人遗留问题。


一些术语的解释:

  • 一个交互式外壳是一个可以交互的 shell。这意味着您可以在其中输入命令。
  • A非交互式 shell是您无法交互的 shell。Shell 脚本在非交互 shell 中运行。
  • A登录外壳是您登录系统时启动的 shell。
  • A未登录shell 是登录过程后启动的shell。

通常,当您在 gnome-terminal 中工作时,您使用 bash 作为交互式非登录 shell。交互式是因为您在其中输入命令。非登录是因为您没有使用该 shell 登录(在这种情况下,gnome 是“登录 shell”)。

除了启动时加载的配置文件之外,登录 shell 和非登录 shell 之间没有太大区别。


更多背景:

互联网上关于将配置放在哪里存在一些混淆。有人说,.bashrc但正如您所经历的,.bashrc并不总是加载。有人说.profile这更正确一些。但它也有警告。一个是,.profile通常只由登录 shell 读取。另一个是,.profile除了 bash 之外,还有更多程序可以读取。因此,必须注意不要将特定于 bash 的内容放入其中.profile

理想情况下,我们只输入.bashrc与 bash shell 本身相关的设置。并输入与.profilebash 无关的环境变量。但由于各种原因,这经常被混淆。其中一些是:

  • bash 设置通常如果放在 中会工作得很好.profile。这是因为.profile,如果读取了 ,通常会被 bash 读取。
  • 与 bash 无关的环境变量在 中运行良好.bashrc。因为 bash 不关心这些变量,但它们被设置,因此它们可以工作。
  • 新手经常分不清哪些设置与 bash 相关,哪些不相关。

更为混乱的是,gnome-terminal 可以被设置为登录 shell,从而以不透明的方式改变行为。

这个问题也有一些可疑的“修复”或解决方法。例如,Debian(和 ubuntu)默认.profile设置为读取.bashrc。实际上,.profile.bashrc都在登录 shell 上读取。但仅限.bashrc于非登录 shell。这反过来导致许多人学会把所有东西都放进去,.bashrc因为它总是被加载。

我觉得这值得怀疑,因为.profile它不是 bash 独有的配置文件。它是许多程序读取的全局配置文件。所以它不应该加载.bashrc。(我知道它是.bashrc有条件加载的,但为什么其他程序甚至必须决定是否加载.bashrc


以下是我推荐的设置配置文件以减少混乱的方法。

创建一个~/.bash_profile文件并放入以下几行(仅限这些行):

[ -f "$HOME/.profile" ] && source "$HOME/.profile"
[ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc"

处理方式.bash_profile是它是 bash 将查找的第一个文件。如果存在,它将不再查找.profile

现在如果 bash 作为交互式登录 shell 启动,它将读取以下文件:

  1. .bash_profile
  2. .profile
  3. .bashrc

如果 bash 作为交互式非登录 shell 启动:

  1. .bashrc

你会看到它.bashrc总是被读取。.profile如果它是一个登录 shell,还会被额外读取。

并且所有其他只想读取的程序.profile都可以这样做,而无需.bashrc混合。

现在输入 bash 特定设置.bashrc。其余的都输入.profile。例如,输入PS1和,而输入和HISTCONTROL.bashrcPATHLC_ALL.profile

你的 RVM 变量应该放在 中.profile。它将在注销和登录后生效。


更多信息

http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files

https://www.baeldung.com/linux/interactive-non-interactive-login-non-login-shells

https://www.baeldung.com/linux/bashrc-vs-bash-profile-vs-profile

https://unix.stackexchange.com/questions/170493/login-non-login-and-interactive-non-interactive-shells

https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell

区分交互式登录和非交互式非登录 shell

请注意,上面的一些文字与我上面所写的内容相矛盾。在所有情况下,我都认为我的观点是更正确的。

答案2

这既不是一个糟糕的设计决策,也不是一个错误,也不是 shell 和终端的预期行为

它只是 Gnome Terminal 中每个配置文件配置选项的一个不幸的默认值,您可以轻松修复它。

  1. 编辑->个人资料偏好

  2. 选择头衔和命令标签。

  3. 注意以登录 shell 身份运行命令复选框未选中!选中它。

就是这样。如果您对Default配置文件或配置为在创建新终端时使用的任何配置文件执行此操作,您将获得一个登录 shell。

我猜测,在底层,这个选项可能会导致它将-l选项传递给 shell。

答案3

我有同样的问题,并找到了一个解决方案:只需使用 SSH 作为真正的登录 shell!

1.以超级用户身份,创建一个专用的rvm系统用户,用于完全隔离,并分配密码:

sudo su

useradd -m rvmuser

passwd rvmuser

2. 安装依赖项,以便 rvm 可以构建 ruby​​ 而无需输入超级用户密码:

apt-get install curl gawk libreadline6-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 autoconf libgdbm-dev libncurses5-dev automake bison libffi-dev

3. 通过 SSH 进入本地主机,获取真正的登录 shell(你可能必须这样做apt-get install ssh

ssh rvmuser@localhost

4. 安装rvm

\curl -sSL https://get.rvm.io | bash -s stable

5. 注销并重新登录,以便加载所有 rvm 功能

exit

ssh rvmuser@localhost

6.使用rvm:)

答案4

使用 bash 时,通常将配置文件初始化放在 中.bash_profile,该初始化仅在登录时由 bash 读取,而其他 shell 历来共享.profile。这允许您将特定于 bash 的命令放在 中.bash_profile

通常使用下列方法来引入在 中定义的别名.bashrc

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

相关内容