问题

我有一个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或profile在缺少这两个文件的情况下会先于bashrc执行。
在这种情况下,我的终端是否为非登录外壳?
如果是这样,为什么在终端后面输入su并在未设置上述出口的地方执行密码却没有执行配置文件呢? br />

#1 楼

~/.bash_profile仅在以登录模式启动时由bash来源。通常是在控制台(Ctrl + Alt + F1..F6)上登录,通过ssh连接或使用sudo -isu -以其他用户身份运行命令时。
以图形方式登录时,~/.profile将是专门由启动gnome-session的脚本(或您使用的任何桌面环境)来源。因此,当您以图形方式登录时,根本不会获取~/.bash_profile
打开终端时,终端以(非登录)交互方式启动bash,这意味着它将提供~/.bashrc
正确的地方您将这些环境变量放在~/.profile中,下次登录时效果应该很明显。
~/.bash_profile购买~/.bashrc是错误的解决方案。应该是相反的。 ~/.bash_profile应该是~/.bashrc的来源。
请参阅DotFiles以获得更详尽的解释,包括为什么这样的历史。包装,这样您就不需要设置JAVA_HOME或更改PATH

评论


我发现从Ubuntu 12的侧栏中打开终端时,不会加载〜/ .profile文件。

– jcollum
13年3月24日在17:20

@jcollum很好。 .profile仅应在登录时提供。

– Geirha
13年3月30日在6:59

哦,打开终端不同于登录。。。我在想登录终端。

– jcollum
13年3月31日在16:53

请记住,如果.bash_profile存在,.profile将被bash忽略。在这里查看我的答案和更多信息。

– terdon
2014年3月11日,0:58

@terdon,是的,但是以图形方式登录时不涉及bash,因此它直接适用于.profile。

– Geirha
2014年3月11日在8:44

#2 楼

您可以通过运行以下命令来检查Bash Shell是否作为登录Shell启动:

shopt login_shell


如果答复为off,则您未运行登录Shell。

阅读Bash手册的调用部分,了解Bash如何读取(或不读取)不同的配置文件。

摘自man bash


什么时候bash是作为交互式登录shell调用的,或者是具有--login选项的
非交互式shell,它首先读取
,并从文件/etc/profile执行命令(如果该文件
存在)。读取该文件后,它将按此顺序查找~/.bash_profile
~/.bash_login~/.profile,并从第一个存在且可读的命令中读取并执行命令。


另一方面,默认情况下,su也不启动登录Shell,您必须使用--login选项告诉它这样做。

评论


非常感谢shotp login_shell命令。太棒了!!

– Viriato
2012年4月11日在18:26

#3 楼

我认为值得一提的是,您可以通过编辑配置文件首选项来更改gnome-terminal的默认值,以使用登录外壳程序(即bash -l)。

转到“编辑”->“配置文件首选项”->“标题和命令”选项卡
,选中“将命令作为登录外壳运行”

评论


启用此设置的不利之处是什么?

–基督
17年11月15日14:30



@chris在很多情况下,您正在加载的代码多于所需的代码。您的〜/ .bash_profile是否真的很快进行评估可能并不重要,这可能就是这种情况。要检查的一件好事是赶走通常很昂贵的对其他进程的所有调用。

–vaab
18 Mar 8'8 at 4:08

我检查了“运行命令作为登录外壳”,但是现在每次打开终端时,都会得到-bash:/home/nikhil/.bash_profile:第1行:寻找匹配项时出现意外的EOF” -bash:/ home / nikhil / .bash_profile:第2行:语法错误:文件意外结束

– Nikhil Shrivastava
20年8月4日在17:33



#4 楼

如果打开终端或运行su,该外壳程序将不作为登录外壳程序执行,而是作为普通的交互式外壳程序执行。因此它读取的是~/.bashrc,而不是~/.bash_profile。您可以使用su选项运行-l,以使其作为登录Shell运行您的Shell。

在使用GUI时,该外壳通常永远不会作为登录Shell运行,因此放置它通常可以~/.bashrc中的所有内容。

评论


那就是我所做的并且有效的方法,但是请检查底部的人说的话,他建议将其放入bashrc并将其放在配置文件中是一个坏主意。 ....两种方法都可以,非常感谢。

– Viriato
2012年4月11日在18:25

#5 楼

TL; DR

在经典推荐的ubuntu设置中,仅在特定情况下对~/.bash_profile进行评估。

将您的内容放入~/.bashrc中,它将得到每次评估。

好,我想理解一下,为什么这很有意义?

了解发生了什么的要点:


Linux上的所有进程都具有并使用环境变量
环境变量是继承的

因此,只需一次将它们设置在所有进程的父级上就足够了(尤其是需要一些计算时间。)
通常在您登录到您的计算机后启动所有进程的父级设备(提供您的凭据)。
有些事情您可能只想在登录时登录一次
(例如检查新邮件...)。

因此,“登录”时间通常为:


在控制台模式下,当您登录(使用Ctrl-Alt F1键)或通过ssh登录时,
因为外壳将是所有进程之父,它将加载您的
~/.bash_profile
在图形模式下,当您打开会话时,第一个进程
gnome-session用于古典ubuntu)将负责阅读.profile

好,那我的东西放在哪里?

这很复杂,全文在这儿。但这是一个ubuntu用户非常普遍的问题。因此,请考虑以下情况:


,您使用bash外壳,
您有一个~/.bash_profile,并按照建议在您的~/.bashrc中添加~/.bash_profile的负载,从而获得
至少有一个文件可以进行评估,无论调用是什么机制。

这是对放置位置的快速建议。



〜/ .bashrc(只要遵循建议,在任何情况下都会得到评估)


仅用户和bash的快速评估环境变量和代码-仅命令行用法(
实例的别名)。欢迎bashism。

它会在以下情况下自动加载:


在图形会话中创建新的shell窗口/窗格。
调用bash


screen new窗格或标签。 (不是tmux!)
如果您不勾选
选项“将命令作为登录shell运行”,则图形控制台客户端中的任何bash实例
terminator / gnome-terminal ...)。 />
由于先前的建议,它将在所有其他情况下加载。


〜/ .bash_profile(仅在特定情况下进行评估)

用于仅用户和控制台会话进程的缓慢评估环境变量和代码。
欢迎流行主义。
它加载到:


控制台登录(Ctrl-Alt F1),

tmux新窗格或窗口(默认设置),(不是screen!)
明确调用bash -l
图形控制台客户端中的任何bash实例
terminator / gnome-terminal ...)仅当您勾选
选项“作为登录外壳运行命令”时。



〜/ .profile(仅在图形会话中评估)

用于缓慢评估的环境变量,且不繁琐
用于仅用户和所有图形会话过程。在您的图形用户界面登录后会
加载该文件。



评论


在bash确实加载配置文件的情况下,如果.bash_profile不存在,它将加载.profile。

–muru
18 Mar 8 '18 at 4:05

非常感谢您的明确解释。它可以帮助像我这样的新手。在Mac Mojave中,如果我将变量放在〜/ .bashrc中并执行源代码,然后执行env,则看不到env变量设置(我尝试关闭iTerm并重新打开)。但是我注意到,当我安装Android Studio和其他应用程序时,所有这些环境变量都在/.bash_profile中设置。因此,当我添加/.bash_profile时,它就像魅力一样工作。这是为什么?

–sofs1
19年8月18日在1:09

令我感到困扰的事情:说有人将装饰性的垃圾/有趣的东西放到〜/ .bashrc中(例如screenfetch / figlet之类的东西),以便他们在打开控制台时获得一些输出。然后,如果他们运行一个做一些简单事情的单行shell脚本,那么它将始终命中.bashrc。因此,将所有内容都放入.bashrc中似乎很疯狂。另外,如果将所有内容都放入.bashrc,那么.bash_profile的意义是什么?我不明白Linux / bash通常很有意义,但这似乎是一个醉酒的人所造成的混乱和自相矛盾的混乱。

–YorSubs
20 Nov 18在22:40



具体来说:•如果我希望代码同时在图形和交互式登录外壳中运行,应该将代码放在哪里? •如果我希望代码仅在图形终端中运行,应将代码放在哪里? •如果我希望代码仅在交互式登录外壳程序中运行,则应将该代码放在哪里?答案似乎是“嗯,bash只是一团混乱的混乱局面,只需将代码放在任何地方,然后尝试插入怪异的连接链,以使事物成为其他事物的源”。真的很奇怪...对吗?

–YorSubs
20-11-18在22:44

#6 楼

当执行sudo su时,不执行外壳程序,而不是尝试使用sudo su -,这将默认加载~/.bash_profile作为源。