2010-09-02 14:40:34 +0000 2010-09-02 14:40:34 +0000
453
453

.bashrc和.bash_profile之间的区别

.bashrc.bash_profile有什么区别,应该用哪个?

答案 (6)

528
528
528
2010-09-02 19:23:14 +0000

传统上,当你登录Unix系统时,系统会为你启动一个程序。这个程序是一个shell,即一个旨在启动其他程序的程序。它是一个命令行shell:你通过输入它的名字来启动另一个程序。默认的shell,即Bourne shell,当它作为登录shell被调用时,从~/.profile读取命令。

Bash是一个类似伯恩的shell。当它作为登录shell被调用时,它从~/.bash_profile读取命令,如果该文件不存在¹,它会尝试读取~/.profile

你可以在任何时候直接调用shell,例如在GUI环境下启动终端模拟器。如果shell不是登录shell,它就不会读取~/.profile。当你以交互式shell的方式启动bash时(即不是为了运行脚本),它读取的是~/.bashrc(除非是以登录shell的方式调用,那么它只读取~/.bash_profile~/.profile

因此:

  • ~/.profile 是放适用于整个会话的东西的地方,比如你想在登录时启动的程序(但不是图形程序,它们会进入另一个文件),以及环境变量定义。

  • ~/.bashrc 是放那些只适用于bash本身的东西的地方,比如别名和函数定义,shell选项,以及提示符设置。(你也可以把键绑定放在那里,但是对于bash来说,它们通常会放到~/.inputrc中。)

  • ~/.bash_profile可以用来代替~/.profile,但它只被bash读取,不被任何其他shell读取。(如果你想让你的初始化文件在多台机器上工作,并且你的登录shell不是在所有机器上都是bash的话,这主要是个问题)。如果shell是交互式的,这是一个逻辑上包含~/.bashrc的地方。我建议在~/.bash_profile中包含以下内容。

在现代的unices上, 有一个额外的复杂情况与~/.profile有关. 如果你在图形环境中登录(也就是说,如果你输入密码的程序是在图形模式下运行的),你不会自动得到一个读取~/.profile的登录外壳。根据图形登录程序,根据你之后运行的窗口管理器或桌面环境,以及根据你的发行版如何配置这些程序,你的~/.profile可能被读取,也可能不被读取。如果没有,通常有另一个地方,你可以定义环境变量和程序,当你登录时启动,但不幸的是没有标准的位置。

注意,你可能会在这里和那里看到一些建议,要么把环境变量定义放在~/.bashrc中,要么总是在终端中启动登录外壳。这两个都是坏主意。这些想法中最常见的问题是,你的环境变量只能在通过终端启动的程序中设置,而不是在用图标、菜单或键盘快捷键直接启动的程序中设置。

¹ 为了完整,根据要求:如果.bash_profile不存在,bash也会先尝试.bash_login,然后再回落到.profile。随意忘记它的存在。

54
54
54
2010-09-02 14:54:04 +0000

从这个短文

根据bash手册页面,.bash_profile是为登录外壳执行的,而.bashrc是为交互式非登录外壳执行的。

*什么是登录或非登录shell? *

当你通过控制台登录(例如:输入用户名和密码)时,无论是开机时坐在机器上,还是通过ssh远程登录:.bash/_profile会在初始命令提示符之前被执行来配置。

但是,如果你已经登录到你的机器,并在Gnome或KDE中打开了一个新的终端窗口(xterm),那么.bashrc就会在窗口命令提示符之前被执行。.bashrc也会在你通过在终端中输入/bin/bash来启动一个新的bash实例时被运行。

35
35
35
2010-09-02 18:10:20 +0000

在以前,当伪TTY不是伪的,而是真正的,好吧,打字的时候,UNIX是通过调制解调器访问的,速度很慢,你可以看到每个字母都被打印到屏幕上,效率是最重要的。为了提高效率,你有一个主登录窗口的概念,以及其他任何你用来实际工作的窗口。在你的主窗口中,你希望收到任何新邮件的通知,可能会在后台运行一些其他程序。

为了支持这一点,shell专门在 “登录shell "上采购了一个文件.profile。这将做特殊的,一旦会话设置。Bash在某种程度上扩展了这一点,先看.bash_profile,再看.profile,这样你就可以把bash专用的东西放在里面(这样就不会把Bourne shell等也看.profile的东西搞坏)。其他的shell,非login的,只需要把rc文件,.bashrc(或.kshrc等)作为源文件。

这个现在有点不合时宜了。你不像登录gui窗口管理器那样登录主shell。主窗口和其他窗口没有任何区别。

我的建议是–不要担心这种差异,它是基于一种旧的使用unix的风格。在你的文件中消除这种差异。.bash_profile的全部内容应该是。

[-f $HOME/.bashrc] && . $HOME/.bashrc

把所有你想设置的东西都放在.bashrc

记住.bashrc是所有shell的源文件,不管是交互式的还是非交互式的。你可以把这段代码放在.bashrc的顶部,以短路非交互式shell的资源:

[[$- != *i*]] && return

19
19
19
2016-07-13 08:53:44 +0000

看看这篇【ShreevatsaR的优秀博文】(http://shreevatsa.wordpress.com/2008/03/30/zshbash-startup-files-loading-order-bashrc-zshrc-etc/)。这是一个摘录,但请去看博文,它包括了一个术语的解释,比如 “登录shell",一个流程图,以及一个类似的Zsh表。

对于Bash,它们的工作原理如下。往下读相应的列。先执行A,再执行B,再执行C,等等。B1, B2, B3意味着它只执行找到的第一个文件。

+----------------+-----------+-----------+------+
| |Interactive|Interactive|Script|
| |login |non-login | |
+----------------+-----------+-----------+------+
|/etc/profile | A | | |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc| | A | |
+----------------+-----------+-----------+------+
|~/.bashrc | | B | |
+----------------+-----------+-----------+------+
|~/.bash_profile | B1 | | |
+----------------+-----------+-----------+------+
|~/.bash_login | B2 | | |
+----------------+-----------+-----------+------+
|~/.profile | B3 | | |
+----------------+-----------+-----------+------+
|BASH_ENV | | | A |
+----------------+-----------+-----------+------+
| | | | |
+----------------+-----------+-----------+------+
| | | | |
+----------------+-----------+-----------+------+
|~/.bash_logout | C | | |
+----------------+-----------+-----------+------+
5
5
5
2016-10-18 18:13:24 +0000

**

# For BASH: Read down the appropriate column. Executes A, then B, then C, etc.
# The B1, B2, B3 means it executes only the first of those files found. (A)
# or (B2) means it is normally sourced by (read by and included in) the
# primary file, in this case A or B2.
#
# +---------------------------------+-------+-----+------------+
# | | Interactive | non-Inter. |
# +---------------------------------+-------+-----+------------+
# | | login | non-login |
# +---------------------------------+-------+-----+------------+
# | | | | |
# | ALL USERS: | | | |
# +---------------------------------+-------+-----+------------+
# |BASH_ENV | | | A | not interactive or login
# | | | | |
# +---------------------------------+-------+-----+------------+
# |/etc/profile | A | | | set PATH & PS1, & call following:
# +---------------------------------+-------+-----+------------+
# |/etc/bash.bashrc | (A) | A | | Better PS1 + command-not-found 
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/bash_completion.sh| (A) | | |
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/vte-2.91.sh | (A) | | | Virt. Terminal Emulator
# |/etc/profile.d/vte.sh | (A) | | |
# +---------------------------------+-------+-----+------------+
# | | | | |
# | A SPECIFIC USER: | | | |
# +---------------------------------+-------+-----+------------+
# |~/.bash_profile (bash only) | B1 | | | (doesn't currently exist) 
# +---------------------------------+-------+-----+------------+
# |~/.bash_login (bash only) | B2 | | | (didn't exist) **
# +---------------------------------+-------+-----+------------+
# |~/.profile (all shells) | B3 | | | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bashrc (bash only) | (B2) | B | | colorizes bash: su=red, other_users=green
# +---------------------------------+-------+-----+------------+
# | | | | |
# +---------------------------------+-------+-----+------------+
# |~/.bash_logout | C | | |
# +---------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-gui)

在 Flimm 的回答的基础上,我在我的 Debian /etc/profile 的头部插入了这个新的注释,(你可能需要根据你的发行版调整它。):

# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

然后在每个其他设置文件的头部插入了这个注释来参考它。

0x1&

值得注意的是,Debian的/etc/profile默认是包括/etc/bash.bashrc的(当/etc/bash.bashrc存在时)。所以登录脚本会同时读取两个/etc文件,而非登录脚本只读取bash.bashrc。

另外需要注意的是,/etc/bash.bashrc在不交互式运行时,被设置为什么都不做。所以这两个文件只适用于交互式脚本。

4
4
4
2019-06-24 22:55:40 +0000

bash的配置逻辑本身并不复杂,在本页的其他答案中,在serverfault和许多博客中都有解释。然而,问题是_Linux发行版对bash做了什么,我的意思是他们默认配置bash的复杂和各种方式。http://mywiki.wooledge.org/DotFiles 简单地提到了一些这些怪癖。这是Fedora 29上的一个跟踪示例,它显示了在一个非常简单的情况下,哪些文件是其他文件的来源,以及顺序:远程连接ssh,然后启动另一个子shell:

ssh fedora29
 └─ -bash # login shell
      ├── /etc/profile
      | ├─ /etc/profile.d/*.sh
      | ├─ /etc/profile.d/sh.local
      | └─ /etc/bashrc
      ├── ~/.bash_profile
      | └─ ~/.bashrc
      | └─ /etc/bashrc
      |
      |
      └─ $ bash # non-login shell
            └─ ~/.bashrc
                 └─ /etc/bashrc
                       └─ /etc/profile.d/*.sh

Fedora最复杂的逻辑是在/etc/bashrc。如上所述/etc/bashrc是一个bash本身不知道的文件,我是说不直接知道。Fedora的/etc/bashrc测试是否。

-是否被登录的shell获取, -是否被交互式shell获取, -是否已经被获取

…… 然后根据这些情况做完全不同的事情。

如果你认为能记住上面的图,那么太糟糕了,因为还远远不够:这个图只是描述了一种情况,在运行非交互式脚本或启动图形会话时,会发生稍微不同的事情。我已经省略了~/.profile。我省略了bash_completion脚本。出于向后兼容的原因,调用bash为/bin/sh而不是/bin/bash会改变其行为。那zsh和其他shell呢?当然,不同的Linux发行版做的事情是不同的,比如Debian和Ubuntu就有一个非标准版本的bash,它有Debian特有的自定义功能。它主要是寻找一个不寻常的文件。/etc/bash.bashrc. 即使你坚持使用单一的Linux发行版,它也可能会随着时间的推移而变化。等等:我们还没有接触到macOS、FreeBSD、…… 最后,让我们为用户想一想,他们的管理员用更有创意的方式配置了他们必须使用的系统。

正如关于这个话题的永无止境的讨论流所表明的那样,这是一个失败的原因。只要你只是想添加新的值,一些 “试错 "往往就足够了。当你想在一个(用户)文件中修改另一个(在/etc中)已经定义的东西时,真正的乐趣才开始。那么就要准备好花一些时间来设计一个永远无法移植的解决方案。

为了最后一点乐趣,这里是2019年6月在Clear Linux上相同的简单方案的 "源图":

ssh clearlinux
 └─ -bash # login shell
      ├── /usr/share/defaults/etc/profile
      | ├─ /usr/share/defaults/etc/profile.d/*
      | ├─ /etc/profile.d/*
      | └─ /etc/profile
      ├── ~/.bash_profile
      |
      |
      └─ $ bash # non-login shell
           ├─ /usr/share/defaults/etc/bash.bashrc
           | ├─ /usr/share/defaults/etc/profile
           | | ├─ /usr/share/defaults/etc/profile.d/*
           | | ├─ /etc/profile.d/*
           | | └─ /etc/profile
           | └─ /etc/profile
           └─ ~/.bashrc
```。