我发现了这个问题[博客]:.bashrc 和 .bash_profile 之间的区别非常有用,但在看到得票最多的答案(顺便说一句,非常好)后,我还有其他问题。在得票最多的正确答案的末尾,我看到了以下陈述:
请注意,您可能会看到一些建议,要么将环境变量定义放在 ~/.bashrc 中,要么始终在终端中启动登录 shell。这两种想法都不太好。
为什么这是个坏主意(我不是想争论,我只是想了解)?
如果我想设置一个环境变量并将其添加到 PATH(例如 JAVA_HOME),那么将导出条目放在哪里最好?的〜/ .bash_profile或者~/.bashrc?
如果问题 2 的答案是的〜/ .bash_profile,我还有两个问题:
3.1. 你会把什么放在~/.bashrc? 仅限别名?
3.2. 在非登录 shell 中,我相信的〜/ .bash_profile没有被“拾取”。如果 JAVA_HOME 条目的导出位于 bash_profile 中,我是否可以执行javac&Java 语言命令?它会在 PATH 上找到它们吗?这就是为什么有些帖子和论坛建议将 JAVA_HOME 等设置为~/.bashrc?
提前致谢。
答案1
在现代系统中,遇到这种情况并不常见,但确实会发生。(特别是,如果您使用诸如vim
或:r !command
内联!<motion>command
形式的 shell 操作。)
您会在 ~/.bashrc 下放置什么?仅别名?
您放入的内容~/.bashrc
不会被子 shell 自动继承;这主要意味着别名和函数,尽管有时您有一些变量设置不希望在 shell 之外可见(这种情况非常罕见)。有人可能会认为这些应该以某种方式导出,但各种实验性尝试在试图将它们隐藏在环境中时遇到了兼容性问题,并且大多已被放弃。
如果我想设置一个环境变量并将其添加到 PATH(例如 JAVA_HOME),那么放置导出条目的最佳位置是哪里?在 ~/.bash_profile 还是 ~/.bashrc?
您输入环境设置,~/.bash_profile
以便它们具有合理的初始设置。有时您会想要覆盖这些设置(通常由 Matlab 或 Cadence 等复杂环境完成);如果您输入环境设置,~/.bashrc
则从这些环境中运行的 shell 将丢失环境的自定义设置,结果可能无法正常工作。如果您使用类似模块,虚拟环境,虚拟机等来管理多个开发环境;输入您的设置~/.bashrc
意味着您无法在编辑器中运行您想要的环境,而是被强制进入系统默认环境。
在非登录 shell 中,我相信 ~/.bash_profile 没有被“拾取”。
这是正确的;你通常希望初始 shell 是登录 shell,并且在该 shell 下启动的任何 shell不是是登录 shell。如果初始 shell 不是登录 shell,则不会有默认设置PATH
或其他各种设置(包括您的JAVA_HOME
示例)。
从显示管理器启动的大多数桌面环境(也就是说,绝大多数图形登录)不会为整个桌面设置登录环境,因此您不得不在终端中将初始 shell 作为登录 shell 运行。这会导致许多问题(特别是,从例如面板PATH
运行的程序可用的 和 等没有正确设置,因为面板不是终端并且没有运行~/.bash_profile
),但这是一个合理的折衷方案,因为在由显示管理器启动的会话开始时,根据其内容,并不总是能够~/.bash_profile
在非交互式环境中正常运行。有时建议将环境设置放在 中,~/.bashrc
而不是配置登录 shell;如上所述,只要您不需要覆盖该环境,这种方法就可以正常工作,并且一旦您做需要这样做。
我最近帮助诊断了 OS X 上的类似问题,一个用户在设置~/.bashrc
之后开始rvm
使用perlbrew看到了奇怪的行为,因为这两个人设置的环境被~/.bashrc
内部编辑器“撤消”了sudo
(在 OS X 上,与 Linux 不同,它会传播用户的环境,$HOME
以便~/.bashrc
由 root shell 运行)。在尝试使用这些环境之前,没有任何问题;在开始使用它们时,他们因设置意外丢失而感到困惑。
答案2
说实话,不管大师怎么说,现在情况并没有什么变化。
这背后的问题是,如今我们是通过图形方式登录,而不是通过登录 shell。在过去,我们 unix 用户喜欢在登录后立即查看服务器上发生的情况的简短报告 - 然后我们将通过命令行启动 X - 这些报告通常需要一些时间来生成(例如 10-20 秒)。然后,我们不想在启动 xterm 时看到相同的内容。因此存在差异。
如今,我认为这种区别不再重要。我认为,现在如果你在 bash_profile 中 source bashrc,没有人会责怪你。
请注意,这不适用于 macos x(启动的每个 terminal.app 都是一个登录 shell)
答案3
嗯,关于“图形登录”,这取决于您使用哪个 *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
有两种情况
- /bin/sh链接到/bin/bash但在“POSIX/Bourne”模式下运行
- /bin/sh是/bin/dash(debian/ubuntu)。速度最快,但功能较少(ShellShock 支持;))
因此 /bin/sh 配置文件是〜/ .profile而不是 ~/.bash_profile, ~/.zprofile
该文件应该用于“与 shell 无关”设置,如路径和环境变量。
不仅登录用户交互的可执行程序应该在这里(邮件检查,财富等......)
~/.*rc 仅适用于“交互式”会话(例如别名...)
bash 和 zsh 在交互方面有区别登录贝壳
bash 源只有 .bash_profile,而 zsh 源的顺序为:
- 〜/ .zprofile
- ~/.zshrc
- ~/zlogin(此处 ~/.zshrc 中定义的别名可用。对于“交互式”+“登录”shell
正确的做法的〜/ .bash_profile在这里得到了答复:
if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
要启用测试(和分析),你可以使用这个
〜/ .bash_配置文件:
#!/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)时才有效
如果你在短跑系统、环境变量和路径设置有效,但是虚拟环境包装器函数定义不起作用,因为脚本不符合 POSIX 标准。
脚本没有给出任何错误,但它结束时没有任何“从事于”定义。
因此,您可以设置手头的环境〜/ .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
但对于虚拟环境包装器你有两种选择:
- 来源于的〜/ .bash_profile或者〜/ .zprofile(或 ~/.zlogin)当终端作为登录 shell 时
- 包括脚本~/.bashrc或者〜/ zshrc
这意味着 X 客户端(例如 emacs)应该从终端 shell 启动,而不是从图形 shell 启动!
“我无法得到满足……”