默认情况下,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 本身相关的设置。并输入与.profile
bash 无关的环境变量。但由于各种原因,这经常被混淆。其中一些是:
- 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 启动,它将读取以下文件:
.bash_profile
.profile
.bashrc
如果 bash 作为交互式非登录 shell 启动:
.bashrc
你会看到它.bashrc
总是被读取。.profile
如果它是一个登录 shell,还会被额外读取。
并且所有其他只想读取的程序.profile
都可以这样做,而无需.bashrc
混合。
现在输入 bash 特定设置.bashrc
。其余的都输入.profile
。例如,输入PS1
和,而输入和HISTCONTROL
.bashrc
PATH
LC_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/38175/difference-between-login-shell-and-non-login-shell
请注意,上面的一些文字与我上面所写的内容相矛盾。在所有情况下,我都认为我的观点是更正确的。
答案2
这既不是一个糟糕的设计决策,也不是一个错误,也不是 shell 和终端的预期行为
它只是 Gnome Terminal 中每个配置文件配置选项的一个不幸的默认值,您可以轻松修复它。
去编辑->个人资料偏好。
选择头衔和命令标签。
注意以登录 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