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


24

Bash手册说:

Bash尝试确定它何时在其标准输入连接到网络连接的情况下运行,就像由远程Shell守护程序(通常为rshd或安全Shell守护程序sshd)执行时一样。如果Bash确定它是以这种方式运行的,则它从〜/ .bashrc读取并执行命令(如果该文件存在并且可读)。

该Bash来源~/.bashrc

ssh user@host :

但是这个Bash来源~/.bash_profile

ssh user@host

根据规范,这两个命令没有区别。在两种情况下,stdin是否都未连接到网络连接?


2
虽然这不是您要问的问题,但我想指出,从.bash_profile中获取.bashrc是一种很好的做法。这样,无论bash是作为登录Shell还是非登录Shell启动,都将应用.bashrc中的设置。
Ilmari Karonen

Answers:


44

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

非登录外壳程序从中读取/etc/bash.bashrc,然后读取~/.bashrc

为什么这么重要?

由于此行中man ssh

如果指定了命令,那么它将在远程主机而不是登录shell上执行。

换句话说,如果ssh命令仅具有选项(没有命令),例如:

ssh user@host

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

一个SSH命令里面确实有一个命令,如:

ssh user@host :

命令在哪里:(或什么都不做)。
不会启动登录外壳,因此~/.bashrc将被读取。


远程标准输入

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

对于:

$ ssh sorontar@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 sorontar sorontar 64 Dec 24 19:34 /proc/self/fd/0 -> /dev/pts/3

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

如开始的bash所见,它以TTY(不是网络连接)结尾。

对于使用命令的ssh连接:

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

TTY的列表以相同的开头,但是请注意/ etc / profile不是源。

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

告诉外壳程序连接是管道(不是网络连接)。

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


no-arg案例是否也有资格通过将其标准输入连接到网络连接来运行并已~/.bashrc读取?
Cyker '16

@Cyker假设外壳将stdin 连接到网络。你为什么这么认为?(答案已编辑,请阅读)。
sorontar '16

编辑的部分是有趣的。看起来ssh在简单执行命令时不会打扰。
赛尔(Cyker)'16

8

您问的是“为什么”而不是“如何”,所以我将尝试从这个角度回答。以下将以大量理由说明过去发生的事情为何导致今天发生的事情。


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

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

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

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

这是在cshbash正在开发期间登录UNIX机器的常用方法。因此~/.profile再次读取仍然继承环境的shell 被认为是浪费的

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

所以,是的,较新版本的bourne shell添加了额外的配置文件,以方便别名和其他快速选项的出现,这些别名和其他快速选项将出现在被GNU屏幕(或类似文件)混和的shell中,但不存在于您第一次输入密码时得到的shell中。机。

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

额外

最喜欢的关于shell启动文件比较的表之一显示了bourne shell兼容shell如何使用profile文件而其他shell不使用。这是因为在过去,最初的外壳(启动多路复用器的外壳)需要是与bourne兼容的外壳。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.