bash_profile或bashrc中的环境变量?


36

我发现了这个问题[blog] :.bashrc和.bash_profile之间的区别非常有用,但是在看到投票率最高的答案之后(非常好),我还有其他问题。在投票最多的正确答案的结尾,我看到以下陈述:

请注意,您可能会在这里和那里看到将环境变量定义放入〜/ .bashrc或始终在终端中启动登录Shell的建议。两者都是坏主意。

  1. 为什么这是个坏主意(我不是想打架,只是想了解)?

  2. 如果我想设置一个环境变量并将其添加到PATH(例如JAVA_HOME)中,这将是放置导出条目的最佳位置?在〜/ .bash_profile〜/ .bashrc中

  3. 如果问题2的答案是〜/ .bash_profile,那么我还有两个问题:

    3.1。你会在〜/ .bashrc下放什么?仅别名?

    3.2。在非登录shell中,我相信〜/ .bash_profile没有被“拾取”。如果JAVA_HOME条目的导出位于bash_profile中,我可以执行javacjava命令吗?它会在PATH上找到它们吗?这就是为什么某些帖子和论坛建议将JAVA_HOME等设置为〜/ .bashrc的原因吗?

    提前致谢。

Answers:


26

在现代系统上,碰到重要的案例并不是特别常见,但是确实会发生。(特别是,如果您使用vim诸如:r !command或内联!<motion>command形式的shell操作。)

你会在〜/ .bashrc下放什么?仅别名?

你把那些东西放进~/.bashrc子shell不会自动继承。这主要是指别名和函数,尽管有时您具有不希望在Shell外部显示的变量设置(这种情况很少见)。可以说应该以某种方式将其导出,但是各种尝试将它们隐藏在环境中都遇到了兼容性问题,并且大多被放弃了。

如果我想设置一个环境变量并将其添加到PATH(例如JAVA_HOME)中,这将是放置导出条目的最佳位置?在〜/ .bash_profile或〜/ .bashrc中?

您放入环境设置,~/.bash_profile以便为它们提供合理的初始设置。有时您会想要覆盖它们(通常是通过Matlab或Cadence等复杂环境来完成);如果将环境设置放在其中,~/.bashrc则在这些环境中运行的Shell将丢失环境的自定义设置,结果可能无法正常工作。如果您使用类似modulesvirtualenvrvm之类的包来管理多个开发环境,这也将适用。放入设置~/.bashrc意味着您无法在编辑器中运行所需的环境,而是将其强制设置为系统默认值。

在非登录shell中,我相信〜/ .bash_profile没有被“拾取”。

这是对的; 您通常希望初始外壳程序是登录外壳程序,并且在该外壳程序下启动的所有外壳程序都不是登录外壳程序。如果初始外壳不是登录外壳,那么您将没有默认设置PATH或其他各种设置(包括您的JAVA_HOME示例)。

从显示管理器启动的大多数桌面环境(也就是说,绝大多数图形登录)都没有为整个桌面设置登录环境,因此您不得不在终端中将初始外壳作为登录外壳运行。这会导致许多问题(尤其是PATH从面板上运行的程序无法正常使用,因为面板不是终端,并且尚未运行~/.bash_profile),但由于并非总是可能,所以这是一个合理的折衷方案。~/.bash_profile在显示管理器启动的会话开始时,根据其内容在非交互式环境中合理运行。有时建议将环境设置放在~/.bashrc而不是配置登录外壳;如上所述,这个作品只要你不需要重写环境,并导致奇破损,一旦你这样做的必要。

我最近在OS X上帮助诊断了一个类似的问题,该用户在其中放置了设置~/.bashrc然后又开始使用rvm并且Perlbrew看到了奇怪的行为,因为这两个设置的环境被~/.bashrc内部编辑器“撤消”了sudo(在OS X上与Linux不同,它会传播用户的内容,$HOME以使其~/.bashrc由root shell运行)。在尝试使用这些环境之前,没有问题。在开始使用它们时,它们被设置的意外丢失所迷惑。


1
我想我知道,我可能需要阅读更多次才能对其进行更多内部化,但是我在总结以下内容。在企业环境中,为了更好地控制自定义外壳,而又没有全局外壳的副作用,最佳做法是将环境变量放入〜/ .bash_profile中。在像Ubuntu或Linux Mint这样的个人环境中,为了正确设置PATH,我应该将它设置在〜/ .bashrc下(甚至在/ etc / profile中)。我对么?
维里亚托2012年

与企业环境的关系比与您是用户还是开发人员的关系要少。像modulesrvm是开发人员工具的系统,以及Matlab和Cadence对“开发人员”的定义有所不同的系统。简单的发展也并不需要他们,但是当你需要对红宝石,Perl中,或Python的多个版本的测试,那么你真的想喜欢的东西rvmperlbrewvirtualenv(分别)周围,以帮助保持它的所有直。
geekosaur'4

2

老实说,尽管大师们不得不说些什么,这些天几乎没有什么不同。

其背后的问题是,如今我们以图形方式登录,而不是通过登录外壳。过去,我们unix用户喜欢在登录后立即查看服务器运行情况的简短报告-然后我们将通过命令行启动X-这些报告通常需要一些时间来生成(例如10-20秒)。然后我们不想在启动xterm时看到相同的内容。因此差异。

如今,我认为区别并不重要。我认为这些天,如果您在bash_profile中获取bashrc,没人会怪您。

请注意,这不适用于macOS X(启动的每个terminal.app都是登录shell)


我不确定我是否完全理解,但是在工作时,通过作为登录外壳的ssh登录时,则bash_profile和bashrc会获得源代码,因此我认为在这种情况下这无关紧要。但是,如果我以图形方式登录(这意味着什么)?喜欢登录我的个人ubuntu吗?
Viriato '04年

在这里同意@bubu的答案-任何~/.bash_profile没有来源的设置都~/.bashrc很难使用并且很难解决。图形化的终端应用程序意味着仅提供〜/ .bashrc并将所有配置都放置在其中更为简单。
RichVel

1

好吧,关于“图形登录”,取决于您使用哪个* DM。

使用GDM(Gnome 3.18),我有以下功能:

/ etc / gdm / Xsession

#!/bin/sh   <= *important*

...

# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"

因此,〜/ .profile是使用/ bin / sh而不是/ bin / bash登录的

有两种情况

  1. / bin / sh链接到/ bin / bash,但以“ POSIX / Bourne”模式运行
  2. / bin / sh/ bin / dash(debian / ubuntu)。最快,但功能较少(ShellShock支持;)

因此/ bin / sh配置文件是〜/ .profile,而不是〜/ .bash_profile,〜/ .zprofile

此文件应用于“外壳不可知”设置,例如路径和环境变量。

NO进行登录,只有用户交互的可执行程序应该是,但这里(邮件检查,财富,等...)

〜/.* rc仅用于“交互式”会话(例如别名...)

bash和zsh的交互式登录 Shell 有所不同

bash仅源.bash_profile,而zsh按以下顺序源:

  1. 〜/ .zprofile
  2. 〜/ .zshrc
  3. 〜/ zlogin(在〜/ .zshrc中定义的别名是可用的。如果是“ interactive” +“ login” shell

在这里回答了正确的〜/ .bash_profile方法

.bashrc和.bash_profile之间的区别

if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

要启用测试(和分析),可以使用此功能

〜/ .bash_profile:

#!/bin/bash

# ------------------------------------------------
export _DOT_BASH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

# ------------------------------------------------
export _DOT_BASH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

〜/ .zprofile:

#!/bin/zsh

# ------------------------------------------------
export _DOT_ZSH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

# no need to source, zsh already handle ~/.zshrc

###case "$-" in *i*) if [ -r ~/.zshrc ]; then . ~/.zshrc; fi;; esac

# ------------------------------------------------
export _DOT_ZSH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

然后,进行测试:

chsh -s /bin/bash

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env


chsh -s /bin/zsh

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env

因此,RVM / virtualenv应该放在〜/ .profile中,恕我直言

但是,这也不行有时 ...

例如,仅当运行Xsession的shell是“原始” bash(导出BASH_VERSION)时,virualenvwrapper才有效

如果您在仪表板上,则环境变量和路径设置有效,但是virualenvwrapper函数定义不起作用,因为该脚本不符合POSIX。

该脚本没有给出任何错误,但是没有任何“ workon”定义就可以结束。

因此,您可以在〜/ .profile中设置环境,只是为了从直接从X启动的客户端中启用正确的python执行:

export VIRTUAL_ENV="/home/mike/var/virtualenvs/myvirtualenv"
export PATH="$VIRTUAL_ENV/bin:$PATH"
unset PYTHON_HOME

https://gist.github.com/datagrok/2199506

https://www.bountysource.com/issues/9061991-setting-up-your-computer-virtualenvwrapper-linux-all

但是对于virualenvwrapper,您有两种选择:

  1. 当终端充当登录外壳时,将其从〜/ .bash_profile〜/ .zprofile(或〜/ .zlogin)中提供
  2. 将脚本包含在〜/ .bashrc〜/ zshrc中

这意味着应该从终端外壳而不是图形外壳启动X客户端(例如,emacs)!

“我不能不满意……”


一个完全不同的故事是使用systemd运行服务。 一些可能的选择是:编写包装脚本,在“服务”定义文件中定义环境,将环境转储到要在父外壳程序中获取的“ env”文件中。RVM / virtualenv使事情变得更加棘手...
hute37
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.