打开终端时为什么〜/ .bash_profile没有获取来源?
问题
我有一个Ubuntu 11.04虚拟机,我想建立我的Java开发环境。 我做了如下
sudo apt-get install openjdk-6-jdk
-
在〜/ .bash_profile中添加了以下条目
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk export PATH=$PATH:$JAVA_HOME/bin
-
保存更改并退出
-
再次打开终端并输入以下内容
echo $JAVA_HOME (blank) echo $PATH (displayed, but not the JAVA_HOME value)
-
没有发生任何事情,比如JAVA_HOME的导出和它对PATH的补充从未完成。
解
我不得不去〜/ .bashrc并在文件末尾添加以下条目
#Source bash_profile to set JAVA_HOME and add it to the PATH because for some reason is not being picked up . ~/.bash_profile
问题
- 为什么我必须这样做? 我认为bash_profile,bash_login或者缺少这两个的配置文件会先在bashrc之前执行。
- 在这种情况下我的终端是非登录 shell吗?
- 如果是这样,为什么当在终端之后做su并输入密码时,为什么我没有执行配置文件,我也设置了上面提到的导出?
在交互式登录模式下启动时, ~/.bash_profile
仅由bash提供。 这通常仅在您在控制台登录( Ctrl + Alt + F1 .. F6 )或通过ssh连接时。
当您以图形方式登录时, ~/.profile
将由启动gnome-session(或您正在使用的任何桌面环境)的脚本专门提供。 因此,当您以图形方式登录时,根本不会获取~/.bash_profile
。
当您打开终端时,终端以(非登录)交互模式启动bash,这意味着它将来源~/.bashrc
。
放置这些环境变量的正确位置在~/.profile
,下次登录时效果应该很明显。
从~/.bashrc
中获取~/.bash_profile
是错误的解决方案。 它应该是另一种方式; ~/.bash_profile
应该来源~/.bashrc
。
请参阅DotFiles以获得更全面的解释,包括其原因的历史。
(另一方面,当通过apt安装openjdk时,应该通过包设置符号链接,这样你就不需要设置JAVA_HOME
或更改PATH
)
您可以通过运行以下命令检查Bash shell是否作为login-shell启动:
shopt login_shell
如果答复已off
您未运行登录shell。
阅读Bash手册的调用部分,了解Bash如何读取(或不读取)不同的配置文件。
摘自man bash
:
当bash作为交互式登录shell或作为具有
--login
选项的非交互式shell调用时,它首先从文件/etc/profile
读取并执行命令(如果该文件存在)。 在读取该文件之后,它按顺序查找~/.bash_profile
,~/.bash_login
和~/.profile
,并从存在且可读的第一个读取和执行命令。
另一方面, su
默认情况下也不启动登录shell,你必须使用--login
选项告诉它这样--login
。
我认为值得一提的是,您可以通过编辑配置文件首选项来更改gnome-terminal的默认值以使用登录shell(即.bash -l)。
转到编辑 – >配置文件首选项 – >标题和命令选项卡,选中“将命令作为登录shell运行”选项
如果您打开终端或运行su
则shell不会作为登录shell执行,而是作为普通的交互式shell执行。 所以它读取~/.bashrc
而不是~/.bash_profile
。 您可以使用-l
选项运行su
,以使其作为登录shell运行shell。
当您使用GUI时,shell通常永远不会作为登录shell运行,因此将所有内容放在~/.bashrc
通常很好。
TL; DR
在经典推荐的ubuntu设置中, ~/.bash_profile
仅在特定场合进行评估。 这是有道理的。
把你的东西放在~/.bashrc
,每次都会得到评估。
好的,我想明白,为什么这有意义?
了解正在发生的事情的关键点:
- Linux上的所有进程都拥有并使用环境变量
- 环境变量是inheritance的
- 因此,在所有过程的父亲上设置它们就足够了(特别是如果它需要一些计算时间。)
- 您登录设备后通常会启动所有进程的父亲(提供您的凭据)。
- 当您登录计算机时,您可能只想做一次事情(例如检查新邮件……)。
所以“登录”时间通常是:
- 在控制台模式下,当您登录(使用Ctrl-Alt F1)或通过
ssh
,因为shell将是所有进程的父亲,它将加载~/.bash_profile
。 - 在图形模式下,当您打开会话时,第一个进程(经典ubuntu的
gnome-session
)将负责读取
.profile
。
好的,那我的东西放在哪里?
它相当复杂, 完整的故事就在这里 。 但是对于ubuntu用户来说这是一个很常见的故障。 所以考虑到:
- 你使用
bash
shell, - 你有一个
~/.bash_profile
并按照建议在~/.bash_profile
中添加~/.bashrc
的加载,以便得到至少一个被评估的文件,无论调用机制是什么 。
这是一个快速建议放置东西的地方。
-
〜/ .bashrc (如果你按照建议, 在任何场合都要进行评估 )
用于快速评估环境变量和代码, 仅用于用户和仅限 bash的命令行用法(例如别名)。 欢迎使用。
它会在以下情况下加载:
- 在图形会话中创建一个新的shell窗口/窗格。
- 打电话给
bash
-
screen
新窗格或选项卡。 (不是tmux
!) - 图形控制台客户端(
terminator
/gnome-terminal
…)中的任何bash实例,如果不勾选选项“run command as login shell”。
由于先前的建议,它将在所有其他场合加载。
-
〜/ .bash_profile ( 仅在特定场合进行评估 )
用于缓慢评估环境变量和用于仅用户和控制台会话进程的代码。 欢迎使用。 它被加载:
- 控制台登录(Ctrl-Alt F1),
- ssh登录到这台机器,
-
tmux
新窗格或窗口(默认设置),(不是screen
!) - 明确调用
bash -l
, - 只有勾选选项“run command as login shell”时,图形控制台客户端(
terminator
/gnome-terminal
…)中的任何bash实例。
-
〜/ .profile (仅在图形会话中获取)
对于缓慢评估的环境变量,对于仅用户和所有图形会话进程都没有基础。 它在您的图形用户界面登录时加载。