![为什么远程 Bash 源是 .bash_profile 而不是 .bashrc](https://linux22.com/image/101611/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%9C%E7%A8%8B%20Bash%20%E6%BA%90%E6%98%AF%20.bash_profile%20%E8%80%8C%E4%B8%8D%E6%98%AF%20.bashrc.png)
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”)是因为过去在机器上工作的常见方式是:
从某种真实终端或其他工作站登录并获得登录外壳。该 shell 将调用
/etc/profile
和~/.profile
并为用户设置环境。调用用户想要进入的环境。该环境可以是 Xorg,但在大多数情况下它是多路复用器,例如 GNU screen。
然后,环境(例如 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。