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

评论

在ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile
上也可以找到类似的问题
如果您想获得也涉及.profile的更完整说明,请查看以下问题:superuser.com/questions/789448/…

此答案还涵盖了stackoverflow.com/questions/415403/…
的某些方面

#1 楼

传统上,当您登录Unix系统时,系统会为您启动一个程序。该程序是外壳,即旨在启动其他程序的程序。这是一个命令行外壳:您可以通过键入另一个程序的名称来启动另一个程序。缺省外壳程序Bourne外壳程序在作为登录外壳程序调用时从~/.profile读取命令。

Bash是类似于Bourne的外壳程序。当它作为登录外壳程序调用时,它将从~/.bash_profile中读取命令,如果该文件不存在¹,它将尝试读取~/.profile

您可以随时直接调用外壳程序,例如通过在GUI环境中启动终端仿真器。如果该外壳程序不是登录外壳程序,则不会显示~/.profile。当您将bash作为交互式外壳程序启动时(即,不运行脚本),它读取~/.bashrc(作为登录外壳程序调用时除外,然后它仅读取~/.bash_profile~/.profile

因此:


~/.profile是放置适用于整个会话的内容的地方,例如您要在登录时启动的程序(但不是图形程序,它们会进入另一个文件),和环境变量定义。
~/.bashrc是放置仅适用于bash本身的内容的地方,例如别名和函数定义,shell选项和提示设置。(您也可以在其中放置键绑定,但是对于bash而言,通常可以使用~/.inputrc。)

可以使用~/.bash_profile代替~/.profile,但是只能由bash读取,不能由任何其他shell读取(如果要使初始化文件工作,这通常是一个问题)在多台计算机上,并且您的登录shell并非对所有计算机都使用bash。)这是合乎逻辑的地方,如果sh ell是交互式的。我在~/.bashrc中推荐以下内容:

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



在现代的Unies上,存在与~/.bash_profile相关的其他复杂问题。如果您在图形环境中登录(即,如果您输入密码的程序正在图形模式下运行),则不会自动获得读取~/.profile的登录外壳。根据图形登录程序,之后运行的窗口管理器或桌面环境以及发行版配置这些程序的方式,可能无法读取~/.profile。如果不是,那么通常在另一个位置可以定义登录时要启动的环境变量和程序,但是很遗憾,这里没有标准位置。

请注意,您可能会在此处看到其中的建议将环境变量定义放在~/.profile中,或始终在终端中启动登录Shell。两者都是坏主意。这两种想法中最常见的问题是,只能在通过终端启动的程序中设置环境变量,而不能在直接通过图标,菜单或键盘快捷键启动的程序中进行设置。

¹为了完整起见,通过请求:如果~/.bashrc不存在,bash也会尝试.bash_profile,然后回落到.bash_login。随时忘记它的存在。

评论


为好帖子+1。还感谢您添加有关“登录图形与登录外壳”的部分...我有一个问题,我以为〜/ .profile总是会为图形/外壳执行...,但是当用户登录时它不会执行通过图形登录。谢谢您解决这个谜。

–特雷弗·博伊德·史密斯(Trevor Boyd Smith)
2011-09-17 21:41

@Gilles:您能否通过示例更详细地说明为什么在每个终端中运行登录Shell是一个坏主意?这仅仅是台式机Linux的问题吗? (我收集到的信息是,每次在OS X Terminal上运行登录外壳程序时,我都没有注意到任何副作用(尽管我通常使用iTerm)。但是那时,我想不到许多我不在乎的环境变量一个终端(也许是HTTP_PROXY?)

–iconoclast
2012年6月12日在16:38

@Brandon如果在每个终端中运行登录Shell,它将覆盖环境提供的环境变量。在日常情况下,您可以使用它,但是当您想在终端中设置不同的变量(例如,尝试使用不同版本的程序)时,它会早晚咬住您:登录外壳将覆盖您的本地设置。

–吉尔斯'所以-不再是邪恶的'
2012年6月12日17:57

可以使用语句〜/ .bash_profile代替〜/ .profile,但如果外壳是交互式的,则还需要包含〜/ .bashrc。误导,因为这些是正交的问题。如果您要使用〜/ .bash_profile或〜/ .profile,则必须在其中使用〜/ .bashrc,如果您希望从那里开始的设置在登录shell中生效。

–彼得·多布罗格斯特(Piotr Dobrogost)
13年6月15日在11:20

@Gilles可以,但是答案中句子的表达方式表明需要包含〜/ .bashrc与选择〜/ .bash_profile而不是〜/ .profile有关,这是不正确的。如果有人在登录时获取的任何类型的脚本中包含〜/ .bashrc(此处为〜/ .bash_profile或〜/ .profile),那是因为他希望将〜/ .bashrc中的设置应用于登录外壳将它们应用于非登录外壳的方式。

–彼得·多布罗格斯特(Piotr Dobrogost)
2013年6月15日12:29



#2 楼

根据bash手册页中的内容,




.bash_profile用于登录
shell,而.bashrc则用于
什么是登录外壳或非登录外壳?

通过控制台登录(例如:键入用户名和
密码)时,要么
引导时物理坐在机器上,或者通过ssh远程坐在计算机上:
.bash_profile被执行以配置
在初始命令
提示符之前的内容。

但是,如果您已经登录
并在Gnome或KDE中打开一个新的终端
窗口(xterm),
,那么.bashrc将在窗口命令提示符。 .bashrc也
在您通过在终端中键入/ bin / bash启动新的bash实例时运行。


评论


轻微更新:“执行”可能是一个有点误导性的术语,它们都是来源。执行的声音听起来像是作为脚本运行的,fork / exec yadda yadda。它在当前shell的上下文中运行。更重要的是,.bashrc的运行频率更高。它会在每次运行bash脚本时运行,也可以在没有.bash_profile的情况下运行。另外,根据您如何设置xterm,您可以创建一个源于.bash_profile的shell。

– Rich Homolka
2010-09-02 17:57

#3 楼

在过去,当伪tty不是伪tty时,实际上,可以键入,并且UNIX被调制解调器访问如此之慢,以至于您可以看到每个字母都被打印到屏幕上,效率是最重要的。为了提高效率,您有一个主登录窗口以及您以前实际使用过的其他任何窗口的概念。在主窗口中,您希望收到任何新邮件的通知,可能在后台运行其他程序。

为了支持这一点,shell专门在“ login shell”上提供了一个文件.profile。一旦建立会话,这将做特别的事情。 Bash对此进行了扩展,使其首先在.profile之前先查看.bash_profile,这样您就可以仅在其中放置bash内容(这样它们就不会弄坏Bourne外壳,等等,它也查看了.profile)。其他非登录外壳将仅提供rc文件.bashrc(或.kshrc等)的源。

现在有点过时了。登录到主shell的次数不及登录gui窗口管理器的次数。主窗口与其他窗口没有任何不同。

我的建议-不用担心这种差异,它基于使用UNIX的较旧样式。消除文件中的差异。 .bash_profile的全部内容应为:

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

,然后将您实际要设置的所有内容放入.bashrc中。

请记住.bashrc是源于所有shell(交互式和非交互式)。您可以通过将以下代码放在.bashrc的顶部附近来缩短非交互式外壳的源代码:

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

评论


这是个坏主意,请参阅我的回答。特别是,您的环境变量将仅在通过终端启动的程序中设置,而不是在直接使用图标或菜单或键盘快捷键启动的程序中设置。

–吉尔斯'所以-不再是邪恶的'
2010年9月2日于19:24

@吉尔斯,我不明白你为什么要这样。如上图所示,如果使用。$ HOME / .bashrc,则.bashrc中的设置将在登录Shell中可用,因此在桌面环境中也可用。例如,在我的Fedora系统上,gnome-session以-$ SHELL -c gnome-session开头,因此读取了.profile。

– Mikel
2012年6月2日在16:25



@PiotrDobrogost哦,是的,Rich的答案还有另一个问题。在.profile中包含.bashrc通常是行不通的,因为.profile可能由/ bin / sh执行,而不是bash执行(例如,在Ubuntu上默认为图形登录),并且该shell可能不是交互式的(例如,对于图形用户)登录)。

–吉尔斯'所以-不再是邪恶的'
13年6月15日在11:24

@Gilles re:根本不建议使用“ .profile中包括.bashrc”(实际上恰恰相反)。答案被编辑了(没有出现),或者您的评论与所讲的不一致。

–迈克尔
13年7月29日在6:17



一般而言,+ 1,但我会在“短路...非交互式外壳的短路”方面增加建议(“ .bashrc的顶部附近:[[$-!= * i *]] && return”) ;我确实希望我的某些.bashrc甚至对于非交互式shell也可以执行,特别是在发出ssh主机名{command}时设置env vars,以便远程命令可以正确执行(即使shell是非交互式的) 。但是稍后应忽略.bashrc中的其他设置。我通常检查TERM = dumb和/或未设置,然后提早纾困。

–迈克尔
13年7月29日在6:30



#4 楼

看看ShreevatsaR撰写的这篇优秀博客文章。这是摘录,但请转到博客文章,其中包括对“登录外壳”,流程图和类似的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      |           |      |
+----------------+-----------+-----------+------+


评论


如果您可以根据提问者的特定需求定制答案,则最好不要在多个问题上发布相同的答案。如果两个问题的答案都完全相同,那么您应该发布一个答案并投票关闭其他问题,以作为原始副本的副本。

–Mokubai♦
16年7月13日在18:13

@Mokubai另一个问题已经被标记为与此重复的问题。

– Flimm
16年7月13日在20:34



@ElipticalView:通过设置为不执行任何操作,您所指的行是:[-z“ $ PS1”] &&返回?我的答案中的表格给出了由Bash运行的脚本列表,而不管脚本的内容如何,​​如果脚本本身具有[-z“ $ PS1”] && return行,那当然会生效,但是我不知道认为这并不意味着我应该改变桌子。

– Flimm
16-10-18在10:51

#5 楼

/ ETC / PROFILE头的更好注释
基于上面Flimm的出色回答,我在Debian /etc/profile的头插入了新注释(您可能需要为发行版进行调整。):
# 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)

在每个其他安装文件的开头都带有此注释,以供参考:
# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

我要注意的是,我认为Debian的/etc/profile是默认来源(包括)/etc/bash.bashrc, (即存在/etc/bash.bashrc的时间)。因此,登录脚本读取两个/etc文件,而非登录仅读取bash.bashrc。
还要注意的是,当/etc/bash.bashrc不能交互式运行时,它设置为不执行任何操作。因此,这两个文件仅用于交互式脚本。

#6 楼

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