.bashrc
和.bash_profile
和应该使用哪一个有什么区别?
.profile
查看以下问题:superuser.com/questions/789448/…–
.bashrc
和.bash_profile
和应该使用哪一个有什么区别?
.profile
查看以下问题:superuser.com/questions/789448/…–
Answers:
传统上,当您登录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,这通常是一个问题。)~/.bashrc
如果shell是交互式的,则这是一个合乎逻辑的地方。我建议在以下内容~/.bash_profile
:
if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
在现代的Uniice上,还有一个与之相关的复杂问题~/.profile
。如果您在图形环境中登录(即,您输入密码的程序正在图形模式下运行),则不会自动获得显示为的登录外壳~/.profile
。根据图形登录程序,之后运行的窗口管理器或桌面环境以及发行版配置这些程序的方式,~/.profile
可能会或可能不会读取您的信息。如果不是这样,通常在另一个地方可以定义登录时要启动的环境变量和程序,但是很遗憾,这里没有标准位置。
请注意,您可能会在这里和那里看到有关将环境变量定义放入~/.bashrc
或始终在终端中启动登录Shell的建议。两者都是坏主意。这两种想法中最常见的问题是,只能在通过终端启动的程序中设置环境变量,而不是在直接通过图标,菜单或键盘快捷键启动的程序中设置环境变量。
¹ 为了完整起见,请提出要求:如果.bash_profile
不存在,bash也会尝试.bash_login
在退回到之前.profile
。随时忘记它的存在。
~/.bash_profile
可以使用~/.profile
~/.bashrc
该语句代替,但如果外壳是交互式的,则还需要包含该语句。误导,因为这些是正交的问题。无论您使用~/.bash_profile
还是~/.profile
必须包括~/.bashrc
在其中,如果您希望从那里进行的设置都在登录外壳中生效。
~/.bashrc
与选择有关,~/.bash_profile
而不是与~/.profile
事实不符。如果有人~/.bashrc
在登录时获取了源脚本中的任何一种(此处为~/.bash_profile
or ~/.profile
),那是因为他希望将来自的设置~/.bashrc
应用于登录shell,就像他们将其应用于非登录shell一样。
从这篇短文
根据bash的手册页,对于登录Shell执行.bash_profile,而对于交互式非登录Shell执行.bashrc。
什么是登录或非登录外壳?
当您通过控制台登录时(例如:键入用户名和密码),或者在引导时实际坐在计算机上,或者通过ssh远程登录:执行.bash_profile以配置初始命令提示符之前的内容。
但是,如果您已经登录到计算机并在Gnome或KDE中打开一个新的终端窗口(xterm),则在窗口命令提示符之前执行.bashrc。通过在终端中键入/ bin / bash启动新的bash实例时,.bashrc也将运行。
在过去,当伪tty不是伪tty时,实际上,可以键入,并且UNIX被调制解调器访问如此之慢,以至于您可以看到每个字母都被打印到屏幕上,效率是最重要的。为了提高效率,您有一个主登录窗口以及您以前实际使用过的其他任何窗口的概念。在主窗口中,您希望收到任何新邮件的通知,也可能在后台运行其他程序。
为此,shell .profile
专门在“ login shell”上提供了一个文件。一旦建立会话,这将做特别的事情。Bash对此进行了扩展,使其首先在.profile之前先查看.bash_profile,这样您就可以只在其中放置bash内容(这样它们就不会弄坏Bourne外壳,等等,它们也查看了.profile)。其他非登录外壳将仅提供rc文件.bashrc(或.kshrc等)的源代码。
现在有点过时了。登录到主shell的次数不及登录gui窗口管理器的次数。主窗口与其他窗口没有任何不同。
我的建议-不用担心这种差异,它基于使用UNIX的较旧样式。消除文件中的差异。.bash_profile的全部内容应为:
[ -f $HOME/.bashrc ] && . $HOME/.bashrc
并将您实际要设置的所有内容都放在.bashrc中
请记住,.bashrc是所有交互式和非交互式shell的源代码。您可以通过将以下代码放在.bashrc的顶部附近来缩短非交互式shell的源代码:
[[ $- != *i* ]] && return
.$HOME/.bashrc
为Rich以上表明,在设置.bashrc
将在登录shell可用,因此桌面的良好环境。例如,在我的Fedora系统上,gnome-session
启动为-$SHELL -c gnome-session
,因此.profile
被读取。
.bashrc
在.profile
通常不工作,因为.profile
可以通过执行/bin/sh
和不bash的(例如在Ubuntu用于通过缺省图形登录),且壳可以不是互动(例如,对于一个图形登录)。
[[ $- != *i* ]] && return
”);我确实希望我的一些代码.bashrc
即使对于非交互式shell也要执行,特别是在发出时设置env vars ssh hostname {command}
,以便可以正确执行远程命令(即使shell是非交互式的)。但是以后的其他设置.bashrc
应该忽略。我通常检查TERM = dumb和/或未设置,然后提早纾困。
看看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 | | |
+----------------+-----------+-----------+------+
[ -z "$PS1" ] && return
?我的答案中的表格给出了Bash运行的脚本列表,而不管脚本的内容如何,如果脚本本身具有line [ -z "$PS1" ] && return
,那当然会生效,但是我认为这并不意味着我应该更改表。
对/ 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设置为在不交互式运行时不执行任何操作。因此,这两个文件仅用于交互式脚本。
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
测试是否:
...然后根据这些内容做完全不同的事情。
如果您认为可以记住上面的图,那就太糟糕了,因为它还不够用:该图仅描述了一种情况,在运行非交互式脚本或启动图形会话时,会发生稍微不同的事情。我已经省略了~/.profile
。我省略了bash_completion
脚本。出于向后兼容性的原因,请以bash身份调用/bin/sh
而不是/bin/bash
更改其行为。zsh和其他shell呢?当然,不同的Linux发行版的处理方式也有所不同,例如Debian和Ubuntu附带了非标准版本的bas h,它具有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