Bash手册说:
Bash 尝试确定它何时在其标准输入连接到网络连接的情况下运行,如由远程 shell 守护程序(通常
rshd)或安全 shell 守护程序执行时sshd。如果 Bash 确定它正在以这种方式运行,它会读取并执行来自 的命令~/.bashrc(如果该文件存在且可读)。
这个 Bash 来源~/.bashrc:
ssh user@host :
Run Code Online (Sandbox Code Playgroud)
但是这个 Bash 来源~/.bash_profile:
ssh user@host
Run Code Online (Sandbox Code Playgroud)
根据规范,我没有看到这两个命令的区别。在这两种情况下,stdin 是否都连接到网络连接?
ImH*_*ere 63
登录 shell 首先读取/etc/profile,然后~/.bash_profile.
非登录 shell 从/etc/bash.bashrc和 然后读取~/.bashrc.
为什么这很重要?
由于这一行man ssh:
如果指定了命令,它将在远程主机上执行,而不是在登录 shell 上执行。
换句话说,如果 ssh 命令只有选项(不是命令),例如:
ssh user@host
Run Code Online (Sandbox Code Playgroud)
它将启动一个登录 shell,一个登录 shell 读取~/.bash_profile.
一个确实有command的 ssh 命令,例如:
ssh user@host :
Run Code Online (Sandbox Code Playgroud)
命令在哪里:(或什么都不做)。
它不会启动登录 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
Run Code Online (Sandbox Code Playgroud)
当启动的 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
Run Code Online (Sandbox Code Playgroud)
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]
Run Code Online (Sandbox Code Playgroud)
它告诉外壳连接是管道(不是网络连接)。
因此,在这两个测试用例中,shell 无法知道连接来自网络,因此不会读取~/.bashrc(如果我们只讨论与网络的连接)。它确实读取了 ~/.bashrc,但出于不同的原因。
gro*_*mal 17
你问的是“为什么”而不是“如何”,所以我会尝试从这个角度来回答。以下将是关于为什么过去发生的事情会导致它们今天如何发生的大量基本原理。
有两个不同的启动文件(“profile”和“rc”)的原因是,过去在机器上工作的常用方法是:
从某种真实终端或其他工作站登录并获得登录 shell。此 shell 将为用户调用/etc/profile和~/.profile设置环境。
调用用户想要进入的环境。这个环境可以是 Xorg,但在大多数情况下,它是一个多路复用器,例如 GNU screen。
然后,环境(例如 GNU 屏幕)将调用额外的(非登录)shell,这些 shell 从父登录 shell 继承环境。
这是在开发csh和bash开发期间登录 UNIX 机器的常见方式。因此,~/.profile无论如何在继承环境的shell中再次读取被认为是浪费。
bash然后添加~/.bashrc这些非登录 shell 的额外配置。 csh(和tcsh)从未为非登录 shell 添加任何类型的“rc”文件。请注意,csh/tcsh不是与 bourne shell(它是 POSIX 的一部分)兼容的 shell bash。另一个与 bourne 兼容的 shellksh添加了一个环境变量(称为ENV),如果定义了该变量,它将用作非登录的运行命令(“rc”)文件ksh。
所以,是的,较新版本的 bourne shell 添加了额外的配置文件,以方便别名和其他快速选项,这些选项将出现在由 GNU 屏幕(或类似程序)混合的 shell 中,但不存在于您第一次输入时获得的 shell 中机器。
随着图形显示管理器 (GDM) 的兴起,“配置文件”文件和“rc”文件之间的区别变得毫无意义,因为 GDM 将拥有自己的初始化文件(例如~/.xinit和~/.xsession)。然后,根据用户的奇思妙想,从 GDM 内部声明的 shell 可以是登录 shell 或非登录 shell,并且非登录 shell 总是具有作为登录 shell 的父级的情况不再适用。
我最喜欢的关于 shell 启动文件比较的表格之一显示了与 bourne shell 兼容的 shell 如何使用这些profile文件,而其他 shell 则没有。这是因为在过去,初始 shell(启动复用器的 shell)需要是一个与 bourne 兼容的 shell。