.bash_profile和.bashrc之间有什么区别?

为了在OS X中为终端创建别名,您可以将别名放在.bash_profile.bashrc文件中。这两者有什么区别,我为什么要选择将别名放在其中一个而不是另一个?


8不是为了打击这里的Unix知识,但Bash是一个纯粹的UNIX怪兽,所以你可能会在合作伙伴网站上获得更好的知识或得到这个问题的多次回答。在unix上有超过200个关于bashrc的问题/答案对。 - bmike
2还有一个.profile文件...请参考Stack Overflow上的这个问题 - Yaakov Baruch
2如果你使用brew install bash并且使用iTerm2,你可以将profile -> command设置为/usr/local/bin/bash,这样默认会在.bash_profile之后加载.bashrc。这还能让你享受到Bash 4的好处... - Ray Foss
如果你在这里想知道为什么终端没有加载.bash_profile,那是因为macOS Catalina从bash切换到了zsh;因此现在你需要使用.zprofile而不是.bash_profile - Quazi Irfan
5个回答

.bash_profile 是用于登录 shell 的执行文件,而 .bashrc 是用于交互式非登录 shell 的执行文件。

当您通过控制台登录(输入用户名和密码),无论是坐在机器旁边还是通过 ssh 远程登录时,.bash_profile 会在初始命令提示符之前执行以配置您的 shell。

但是,如果您已经登录到计算机并打开一个新的终端窗口(xterm),那么在窗口命令提示符之前会执行 .bashrc。当您在终端中键入 /bin/bash 启动一个新的 bash 实例时,也会运行 .bashrc

在 OS X 上,默认情况下,Terminal 每次都会运行登录 shell,所以这与大多数其他系统有些不同,但您可以在首选项中进行配置。


109在OS X上,默认情况下,终端每次运行时都会执行登录shell。我一直对此感到困惑,没有意识到这一点。非常有用的信息! - vaughan
7我使用的是OS X操作系统,而不是bash,我使用的是zshell,并且使用的是iTerm而不是Terminal。尽管我使用的终端和shell与答案中讨论的不同,但OS X似乎仍然将所有内容视为登录shell,因为每次都会运行.zprofile文件。 - Adam Zerner
4对于那些寻求详细解释登录/非登录和交互/非交互shell以及它们何时运行这些配置文件的人,请参阅https://unix.stackexchange.com/a/46856/38715。 - kevinmicke
这是一个非常好的答案。它帮助我理解为什么在Ubuntu或Fedora上安装RVM后,我总是需要手动操作才能使其正常工作,即将 [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function* 这一行从 ~/.bash_profile 复制粘贴到 ~/.bashrc 文件中。RVM似乎会自动安装自己,就好像它总是在Mac上被安装一样。它假设每次启动终端时都会以登录shell模式运行。如果您以不同方式使用计算机,只登录一次,那么您需要进行一些调整。 - Matt Welke
需要注意的是,一个新的Terminal.app窗口或选项卡将会寻找并使用~/.bash_profile~/.profile作为上述提到的资源,但如果你使用类似于exec bash或从新窗口/选项卡中生成bash,它只会寻找并使用~/.bashrc。为了避免这种情况,可以使用exec bash -lbash -l来生成一个新的'login' shell,这样它就会寻找.bash_profile/.profile。对于在tmux/screen中创建的新窗口也是一样,它们只会使用~/.bashrc - cmaceachern

X11会查看你的.bashrc,而“常规”的终端会查看.bash_profile

然而,如果你在.bash_profile中添加以下内容,你可以将所有内容移动到.bashrc文件中,以便将所有东西汇总到一个地方而不是两个:

if [ -f $HOME/.bashrc ]; then
        source $HOME/.bashrc
fi

或者你可以直接执行cd ~ ; ln -s .bashrc .bash_profile - lhf
7这两个配置文件有明确的分工。在某些情况下,有必要在会话开始时进行初始化,并且仅在那里(~/.bash_profile)。同时,在每个 shell 级别逐步定义一些内容也是经常需要的(~/.bashrc)。建议取消这种自由并不是最好的主意。 - dan
4@danielAzuelos:Lurch漏掉了一点,但是OS X终端对于每个新的窗口/标签都会读取~/.bash_profile文件,所以从终端的角度来看,实际上没有办法将这两者分开。 - mipadi
21@mipadi 还是将它们分开有一定的价值。例如,.bash_profile 在子进程中永远无法再次被引用。每个嵌套的 Bash 层级都会引用 .bashrc,所以如果你在 .bashrc 中放置类似 export A=a:$A 的内容,你的 $A 变量在嵌套的 Bash 中会变得更长。我通常将环境变量放在配置文件中,而将别名放在 RC 文件中。 - Franklin Yu
@FranklinYu 对很多人来说可能不是什么大事,但我完全同意!这是一个很好的技术观点,值得更多的赞同。 - Subfuzion
我看到类似于<. ~/.bashrc>而不是<source ~/.bashrc>的东西,它们有什么区别吗? - dingx
@DingxinXu 在文件路径前面的点(例如 . ~/.bashrc)是一个source的快捷方式,所以没有区别。请参考https://unix.stackexchange.com/questions/114300/whats-the-meaning-of-a-dot-before-a-command-in-shell - deadvoid
1这个有一个问题。当你在终端中运行 source .bashrc,而 .bash_profile 中有 if [ -f $HOME/.bashrc ]; then source $HOME/.bashrc fi 这段代码时,会导致 .bashrc 中添加的路径重复。 - John

对于macOS,将以下代码放入.bash_profile以将所有内容整合到.bashrc中:
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi

这更适用于Mac终端用户。

19虽然没错,但这与Lurch在2012年的回答有何不同? - Arjan

TLDR; 使用`.bash_profile`来设置你的别名。
不同的初始化文件之间的工作方式有点复杂,并且在OSX中有一些重要的特殊情况。以下是要点:
Bash在任何平台上执行一个或多个不同的文件,取决于它的调用方式。详细信息请参阅这里
OSX的Terminal应用程序做了一些非标准的事情:它将每个新的标签页或窗口创建为登录shell,这意味着会调用.bash_profile。因此,上面的TLDR建议适用。 .bashrc也是一个选项,但每次创建子shell(即调用bash)时都会调用它,这可能会导致效率低下,特别是当您在其中更新变量(例如PATH=/bin/foo:$PATH)时。
其他具有嵌入式终端的应用程序可以选择遵循Terminal应用程序的约定与否。值得注意的是,默认情况下,Visual Studio Code并没有遵循
通过GUI调用的应用程序不是从shell中衍生出来的。因此,为了让它们看到环境变量,存在着竞争的机制,这些机制在多年间已经发生了变化
.bash_profile调用.bashrc的片段非常常见。

1为什么使用.bash_profile来设置别名会变得复杂呢?你列出的项目只是部分涉及到别名,所以除了简单地列举一些可能解释“为什么”它似乎很复杂的要点之外,你是否可以提出一种在这些限制条件下使其更加简便的方法呢? - nohillside
我明白你的意思。使用.bash_profile并不复杂,复杂的是文件的调用方式。我会进行更新。 - Leo
1在GNU bash手册中建议从.bash_profile调用.bashrc - 否则,你如何设置需要在登录shell和非交互式shell中都使用的变量等呢? - mmmmmm
每个我在不同操作系统上使用的终端仿真器都有一个选项,可以将新窗口作为登录 shell 运行,举例来说就有 xterm 和 Xfce。 - fd0

对于Ubuntu/Debian,我将以下代码添加到`.bashrc`的末尾:
 if [ -f ~/.bash_profile ]; then
    source ~/.bash_profile
 fi

现在我的别名在所有新打开的终端(或选项卡)中生效。