连接到 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 远程运行命令时,命令stdout
和stderr
流将发送到本地stdout
和stderr
,这意味着您可以单独重定向/管道它们 - 例如:
$ 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 操作系统的计算机时,这个噩梦会变得更糟。
没有简单的解决方案,必须将一种情况作为默认情况。