.bashrc和.bash_profile之间的区别
Bash是大多数Linux发行版中的默认Shell,并且功能强大,因为它也支持许多编程功能。
例如,bash支持条件语句,例如if和else,变量,case语句,循环等等。
在本文中,我们将尝试探索bash shell启动时使用的两个主要配置文件。
我之所以决定写这本书的原因是由于对这两个配置文件的困惑和怀疑。
主要是因为两者都可以用于相似的目的,所以为什么要用两个文件而不是一个文件。
我在这里谈论的配置文件是“ .bashrc”和“ .bash_profile”。
两者都位于用户的主目录中。
这两个文件在启动时都会被bash shell读取。
让我们深入研究并了解它们的主要差异。
在介绍配置文件用例之前,让我们了解bash支持的不同类型的Shell会话。
我们讨论登录类型的原因是因为bash及其读取的文件的行为取决于shell会话类型。
什么是交互式和非交互式Shell?
我们可以轻松地猜出这一个。
一个shell进程是一个交互式shell,其文件描述符0、1和2指向终端设备(/dev/tty或者/dev/pts/0等)。
是的,我知道如果我们是Unix/Linux的新手,那很难理解。
让我这样说吧。
可以其中键入命令(由文件描述符0指示的STDIN)并查看输出(由文件描述符1指示的STDOUT)和错误(由2指示的STDERR)的shell可以视为交互式shell。
非交互式shell程序基本上是由其他程序启动的shell程序。
例如cron。
或者以SHEBANG开头的脚本(shebang是#!/bin/bash。
大多数脚本的第一行是相同的)。
Bash中的登录shell是什么?
当我们SSH到远程服务器时,ssh程序实际上会触发登录程序(它将实习生读取/etc/login.defs文件并验证密码,shell名称,主目录以及/etc/passwd文件中的内容)。
身份验证成功后,ssh程序将随后触发shell程序,如下所示。
execve("/bin/bash", ["-bash"])
execve是一个系统调用,用于使用内部程序启动进程。
我通过使用strace命令跟踪在登录过程中发生的系统调用发现了这一点。
这里要注意的最重要的事情是execve中的“ -bash”。
为什么要连字符?
为什么不简单地“bash”呢?
这是因为传统上任何触发Shell的程序都使用加在破折号/连字符(“-”)前面的方法来将其表示为登录Shell。
许多shell程序将此视为了解它是否是登录shell程序的信号。
我们也可以通过查看源代码来确认ssh的这种行为。
在此处查看行号1637:https://github.com/openssh/openssh-portable/blob/master/session.c
bash手册页对此进行了确认。
请参阅我从下面的bash手册页中摘录的片段(即man bash)。
INVOCATION A login shell is one whose first character of argument zero is a -, or one started with the --login option.
确认我们是否在登录shell中的另一种简单方法是执行以下echo命令(它将显示正在运行的进程的第0个参数)。
它将显示用于启动Shell的bash命令。
请参见下面的输出中的连字符。
ubuntu@localhost:~$echoif [ -f ~/.bashrc ]; then . ~/.bashrc fi-bash
仔细阅读前面显示的手册页片段。
它还指出,如果bash也以--login选项开头,则它将充当登录shell(在这种情况下,我们不会看到连字符作为前缀。
两者中的任何一个)。
现在让我们看看bash作为登录shell(交互或者非交互)触发时的作用。
换句话说,在使用ssh或者终端登录时,或者使用--login参数从已经存在的shell中执行bash时。
它执行以下操作。
- 首先,它尝试读取/etc/profile文件(如果不存在,则继续进行以下操作。如果存在,则将执行该文件,然后继续进行下面提到的项)
- 它搜索名为~/.bash_profile的文件(即:在用户的主目录下的名为.bash_profile的文件。如果找到该文件,则将执行该文件,然后不查找下面提到的任何内容。)
- 如果不存在~/.bash_profile,它将查找另一个名为~/.bash_login的文件(同样在用户的主目录中,如果找到它,将执行该文件,然后不查找下面提到的任何内容。)
- 如果主目录中不存在.bash_profile和.bash_login文件,则它将查找名为.profile的文件(同样在用户的主目录中)。实际上,几乎所有shell程序都读取该.profile(即:bash以外的其他shell程序)
到目前为止,我们要了解的主要事情是,如果bash shell作为登录shell启动(无论它是交互式的还是非交互式的),那么它不会读取.bashrc文件。
它只读取.bash_profile文件。
现在让我们看看.bashrc何时出现。
Bash何时读取.bashrc文件?
当bash shell在交互模式下作为非登录shell启动时,它将读取.bashrc。
最好的例子是执行命令bash时。
好,下面是配置查找的实际流程。
- 它首先搜索名为/etc/bash.bashrc的文件,如果该文件存在,则执行该文件并继续执行以下操作
- 它搜索名为.bashrc的文件(在用户的主目录下),如果找到,它将执行该文件。
我应该使用.bash_profile还是.bashrc?为什么要使用两个不同的文件?
两个不同的文件,因为它们具有不同的用途。
特定于登录会话的内容应放在.bash_profile中。
bash shell本身特有的内容应转到.bashrc。
让我们考虑一个例子。
设想一下我们希望有人登录时发生某些事件的情况。
用户登录后,可能会发送包含用户详细信息和其他系统统计信息的API调用/电子邮件警报。
如果在.bashrc中添加此类逻辑,即使用户启动了新的终端(不是登录名),它也将不必要地触发该事件。
因此,最好在.bash_profile中添加此类内容,而不是在.bashrc中添加此类内容。
最好的方法是将bash常见的内容放在.bashrc内,然后将下面的内容放在.bash_profile内。
##代码##这样,在从.bash_profile执行登录特定/会话特定的操作之后,登录shell将始终调用.bashrc(并获得bash特定的配置)。
实际上,某些发行版已经做到了。