`ssh <host>` 是登录 shell,而 `ssh <host> <command>` 不是?

Rya*_*Lue 13 linux ssh bash bashrc .bash-profile

我注意到,当我使用ssh <host> <command>语法直接在 SSH 主机上运行命令时,我看到的是输出,.bashrc但没有看到.bash_profile(或.profile)的输出。

例如,如果我将以下命令放在两个文件的顶部,

echo ${BASH_SOURCE[0]}
Run Code Online (Sandbox Code Playgroud)

和手动来源.bash_profile.bashrc依次来源),我会看到

$ . .bash_profile
.bash_profile
.bashrc
Run Code Online (Sandbox Code Playgroud)

这与我使用ssh <host>命令的形式通过 SSH 远程登录到这台计算机时看到的输出相同。(如果我.bash_profile暂时存放在其他地方,这两行都不会得到回应。)

但是,如果我直接在远程机器上以ssh <host> <command>形式执行命令ssh,则输出如下所示:

$ ssh <host> echo foo
/home/rlue/.bashrc
foo
Run Code Online (Sandbox Code Playgroud)

我的理解是,之间的区别.bash_profile,并.bashrc就在于前者是登录shell而后者则是互动的,非登录shell

我得出了以下结论:

  1. ssh <host>仅来源.bash_profile,而
  2. ssh <host> <command>仅来源.bashrc,这意味着
  3. 前者是登录shell,后者不是。

这些结论是否正确?为什么被ssh <host> <command>视为交互式、非登录 shell?SSH不是还在登录远程机器执行命令吗?

Eri*_*ouf 12

OpenSSH(很可能是您正在运行的)决定是否创建登录 shell,并且只有在您没有运行特定命令时才会这样做。来自man ssh

 If command is specified, it is executed on the remote host instead of a
 login shell.
Run Code Online (Sandbox Code Playgroud)

所以它是ssh服务器的一个实现选择,它是否要创建一个登录shell,如果你给一个命令运行,它不会。

虽然ssh确实执行了登录,但如果您让它执行命令并退出,它实际上更类似于创建一个 shell 来运行该命令,而不是获取登录环境。鉴于此,编写 OpenSSH 的人似乎决定将其视为此类任务。

他们创建了一个非交互式、非登录的 shell 来执行命令,因为这是在另一个上下文/shell 中运行命令的精神。但是,通常情况下,非交互式 shell 不会自动获取源代码~/.bashrc,这在这里显然发生了。 bash实际上是在试图帮助我们。从文档

由远程 shell 守护进程调用

Bash 尝试确定它何时在其标准输入连接到网络连接的情况下运行,就像由远程 shell 守护程序(通常是 rshd)或安全 shell 守护程序 sshd 执行时一样。如果 Bash 确定它正在以这种方式运行,它会从 ~/.bashrc 读取并执行命令,如果该文件存在且可读。如果作为 sh 调用它不会这样做。--norc 选项可用于禁止这种行为,--rcfile 选项可用于强制读取另一个文件,但 rshd 和 sshd 通常都不会使用这些选项调用 shell 或允许指定它们。