为什么远程 Bash 源是 .bash_profile 而不是 .bashrc

为什么远程 Bash 源是 .bash_profile 而不是 .bashrc

bash手册说:

Bash 尝试确定它何时使用连接到网络连接的标准输入运行,例如何时由远程 shell 守护程序(通常为rshd)或安全 shell 守护程序执行sshd。如果 Bash 确定它正在以这种方式运行,那么它会从 读取并执行命令~/.bashrc(如果该文件存在并且可读)。

这个 Bash 来源~/.bashrc

ssh user@host :

但是这个 Bash 来源~/.bash_profile

ssh user@host

根据规范,我没有看到这两个命令有什么区别。在这两种情况下,标准输入是否都没有连接到网络连接?

答案1

登录 shell 首先读取/etc/profile,然后读取~/.bash_profile

非登录 shell 读取/etc/bash.bashrc和 then ~/.bashrc

为什么这很重要?

由于以下行man ssh

如果命令指定后,它会在远程主机上执行,而不是在登录 shell 上执行。

换句话说,如果 ssh 命令只有选项(而不是命令),例如:

ssh user@host

它将启动一个登录 shell,登录 shell 读取~/.bash_profile.

一个 ssh 命令确实有一个命令, 喜欢:

ssh user@host :

命令所在的位置:(或不执行任何操作)。
它会不是启动登录 shell,因此~/.bashrc将读取内容。


远程标准输入

为远程计算机中的 /dev/stdin 提供的 tty 连接可能是实际的 tty 或其他东西。

为了:

$ ssh isaac@localhost
/etc/profile sourced

$ ls -la /dev/stdin
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

$ ls -la /proc/self/fd/0
lrwx------ 1 isaac isaac 64 Dec 24 19:34 /proc/self/fd/0 -> /dev/pts/3

$ ls -la /dev/pts/3
crw--w---- 1 isaac tty 136, 3 Dec 24 19:35 /dev/pts/3

正如启动的 bash 所看到的那样,它以 TTY(不是网络连接)结束。

对于使用命令的 ssh 连接:

$ ssh isaac@localhost 'ls -la /dev/stdin'
isaac@localhost's password: 
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

TTY 列表的开头相同,但请注意 /etc/profile 未来源。

$ ssh isaac@localhost 'ls -la /proc/self/fd/0'
isaac@localhost's password:
lr-x------ 1 isaac isaac 64 Dec 24 19:39 /proc/self/fd/0 -> pipe:[6579259]

它告诉 shell 该连接是管道(而不是网络连接)。

因此,在这两个测试用例中,shell 无法知道连接来自网络,因此不会读取~/.bashrc(如果我们只讨论与网络的连接)。它确实读取 ~/.bashrc,但出于不同的原因。

答案2

你问的是“为什么”而不是“如何”,所以我会尝试从这个角度来回答。以下将详细解释为什么过去发生的事情会导致今天的发生。


之所以有两个不同的启动文件(“profile”和“rc”)是因为过去在机器上工作的常见方式是:

  1. 从某种真实终端或其他工作站登录并获得登录外壳。该 shell 将调用/etc/profile~/.profile并为用户设置环境。

  2. 调用用户想要进入的环境。该环境可以是 Xorg,但在大多数情况下它是多路复用器,例如 GNU screen。

  3. 然后,环境(例如 GNU 屏幕)将调用额外的(非登录)shell,这些 shell 从父登录 shell 继承环境。

csh这是在开发期间登录 UNIX 计算机的常见方式bash。所以~/.profile再次阅读被认为是浪费无论如何,在继承环境的 shell 中。

bash然后添加~/.bashrc这些非登录 shell 的额外配置。 csh(和tcsh)从未为非登录 shell 添加任何类型的“rc”文件。请注意,csh/tcsh不是与 bourne shell(POSIX 的一部分)兼容的 shell,而与 bourne shell 兼容bash。另一个 bourne 兼容 shellksh添加了一个环境变量(称为ENV),如果定义了该环境变量,将用作非登录的运行命令(“rc”)文件ksh

所以,是的,较新版本的 bourne shell 添加了额外的配置文件,以方便使用别名和其他快速选项,这些选项将出现在由 GNU 屏幕(或类似)混合的 shell 中,但不会出现在您第一次进入时获得的 shell 中。机器。

随着图形显示管理器 (GDM) 的兴起,“profile”文件和“rc”文件之间的区别变得毫无意义,因为 GDM 将拥有自己的初始化文件(例如~/.xinit~/.xsession)。然后,GDM 内部声明的 shell 可以是登录 shell,也可以是非登录 shell,具体取决于用户的想法,并且非登录 shell 始终具有登录 shell 的父级的情况不再成立。

额外的

我的一个最喜欢的桌子关于 shell 启动文件比较显示了 bourne shell 兼容 shell 如何使用这些profile文件,而其他 shell 则不然。这是因为在过去,初始 shell(启动复用器的 shell)需要是 bourne 兼容的 shell。

相关内容