当 ssh 客户端的参数后面跟着一个交互式程序时,为什么 sshd 不使用伪终端?

当 ssh 客户端的参数后面跟着一个交互式程序时,为什么 sshd 不使用伪终端?

连接到 SSH 服务器的正常方法是ssh username@ip_address。但用户可能只想在远程计算机上运行程序。因此程序名称跟在正常参数之后,即ssh username@ip_address <program_name>.例如,ssh username@ip_address ls。这个论点很好,除了交互式程序(也接受用户输入并提供输出),例如top。输出是

未设置 TERM 环境变量。

这意味着 sshd 和 top 程序之间没有连接(伪)终端。解决方案是-t在整个命令现在变为 的位置添加参数ssh -t username@ip_address top

我的问题是为什么 sshd 默认情况下不能也使用伪终端与非交互式程序进行通信,因此不需要-t为交互式程序添加参数?

答案1

确实,正如其他人所说,PTY 具有一定的开销 - 但在运行远程命令时不使用 PTY 的一个重要原因是您会丢失信息。

通常,当您通过 ssh 远程运行命令时,命令stdoutstderr流将发送到本地stdoutstderr,这意味着您可以单独重定向/管道它们 - 例如:

$ ssh server ls foo bar
ls: cannot access bar: No such file or directory
foo
$ ssh server ls foo bar > stdout 2> stderr
$ cat stdout
foo
$ cat stderr
ls: cannot access bar: No such file or directory

但如果您使用 PTY,所有输出都会转到stdout,因为 PTY 没有单独的输出/错误流:

$ ssh -t server ls foo bar > stdout 2> stderr
$ cat stdout
ls: cannot access bar: No such file or directory
foo
$ cat stderr
$

答案2

手册页ssh对此进行了描述:

当服务器接受用户的身份时,服务器要么在非交互式会话中执行给定的命令或者,如果未指定命令,则登录计算机并为用户提供普通 shell 作为交互式会话。所有与远程命令或 shell 的通信都将自动加密。

这是一种特征,并且可能是由行为的历史原因引起的rsh。这是相当合理的。大多数命令实际上不是交互式的,分配 PTY 也不是自由操作(这在 20 年前更为重要)。

答案3

如何ssh判断您正在调用的命令是否是交互式的?

当您意识到自己可能登录到运行非 UNIX 操作系统的计算机时,这个噩梦会变得更糟。

没有简单的解决方案,必须将一种情况作为默认情况。

相关内容