-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
主要区别在于交互性的概念。这类似于在脚本中本地运行命令,而不是自己输入命令。不同之处在于远程命令必须选择默认值,非交互是最安全的。(通常是最诚实的)
标准输入
Ctrl-c
中断通常会导致 ssh 命令上的循环立即中断,但您的控制序列将改为发送到远程服务器。这导致需要“敲击”击键以确保它在控制离开ssh 命令时但在下一个 ssh 命令开始之前到达。我会警告不要
ssh -t
在无人看管的脚本中使用,例如 crons。要求远程命令以交互方式进行输入的非交互式 shell 会带来各种麻烦。您还可以在自己的 shell 脚本中测试终端是否存在。使用较新版本的 bash 测试 STDIN:
标准输出
ssh
为 时ssh -t
,你可以期望在你的行尾得到一个额外的回车。您可能看不到它,但它就在那里;它会显示为^M
当管道传输到cat -e
. 然后,您必须付出额外的努力来确保不会将该控制代码分配给您的变量,特别是如果您要将该输出插入到数据库中。这是与之前相同的 bash 测试,但针对 STDOUT:
虽然可以解决这些问题,但您不可避免地会忘记围绕它们设计脚本。我们所有人都在某个时候做。您的团队成员也可能没有意识到/记得这个别名已经存在,这反过来会在他们编写使用您的别名的脚本时给您带来问题。
别名
ssh
为ssh -t
在很大程度上违反了最小意外的设计原则;人们会遇到他们没有预料到的问题,并且可能不明白是什么原因造成的。SSH 转义/控制字符和二进制文件的传输
其他答案中没有提到的一个优点是,在没有伪终端的情况下运行时,不支持SSH转义字符等;这使得程序可以安全地传输可能包含这些和其他控制字符的二进制文件。
~C
如果没有伪终端,字符将“按原样”传输到远程主机:
如果您尝试强制分配一个伪终端,包含
~C
会导致ssh>
打印提示以允许用户输入 SSH 命令,从而中断传输。序列更
~.
糟糕,因为它导致没有数据被传输:软件流控
分配伪终端时,也可以对软件流控制字符(XON/XOFF)进行特殊处理。
使用伪终端,该
Ctrl-S
字符被解释为暂停输入流的信号,因此在遇到该字符后不能再发送数据(除非它后面Ctrl-Q
是输入流中的字符)。在这种情况下,强制分配伪终端会导致远程端的文件为空。
在这种情况下,强制分配伪终端会导致远程端的文件包含所有三行但没有控制字符:
行尾字符的转换
使用伪终端,换行字符(十进制 10,
0A
ASCII 中的十六进制)也被转换为CRLF
序列(0D0A
ASCII 中的十六进制)。从前面的例子:
使用伪终端复制二进制文件
在不使用伪终端的情况下复制二进制文件:
这两个文件不一样:
使用伪终端复制的那个已损坏:
而另一个不是:
通过 SSH 传输文件
这对于诸如使用 SSH 进行数据传输的程序尤其
scp
重要rsync
。对 SCP 协议如何工作的详细描述解释了 SCP 协议如何由文本协议消息和二进制文件数据的混合组成。OpenSSH 帮助保护您免受自己的伤害
值得注意的是,即使使用了该
-t
标志,如果 OpenSSH客户端检测到其流不是终端ssh
,它也会拒绝分配伪终端:stdin
您仍然可以强制 OpenSSH 客户端分配一个伪终端
-tt
:在任何一种情况下,它(明智地)都不关心是否
stdout
或被stderr
重定向:在远程主机上,我们必须使用此设置:
没有须藤
和 sudo
使用 sudo 我们得到额外的回车
解决方案是禁用转换换行符到回车换行符
stty -onlcr
考虑向后兼容性。
ssh 的两种主要模式是带 pty 的交互式登录和不带 pty 的指定命令,因为它们分别是
rlogin
和的确切功能rsh
。ssh 需要提供rlogin
/rsh
功能的超集才能成功作为替代品。所以默认值是在 ssh 诞生之前决定的。必须使用新选项访问诸如“我想指定一个命令并获得一个 pty”之类的组合。很高兴至少我们现在有了这个选项,不像我们以前使用
rsh
. 我们没有放弃任何有用的功能来获得加密连接。我们有奖励功能!来自
man ssh
:这允许您获得远程服务器的各种“外壳”。对于不授予 shell 访问权限但允许 SSH 的服务器(即,Github 是 SFTP 访问的一个已知示例),使用此标志将导致服务器拒绝您的连接。
shell 还包含所有环境变量(如
$PATH
),因此执行脚本通常需要一个 tty 才能工作。