打开SSH字符编码问题

打开SSH字符编码问题

我被要求在我们的几个服务器上用 OpenSSH 替换旧的不安全版本的 FreeSSH,现在遇到了一个似乎与字符编码类型有关的问题。

我们有一个批处理文件和 python/fabric 脚本,用于执行一些软件的安装。

该脚本启动一个 ssh 会话,在这种特定的安装中,该会话恰好是同一台服务器上的不同用户(但可能会有所不同,因为相同的通用代码用于安装可能位于不同服务器上的其他软件)。

脚本运行命令,返回垃圾/损坏的字符,例如,在某个时候,它会运行一个ver命令来检查它正在运行的操作系统类型并返回,[2J而不是Microsoft Windows ..

在安装了 open ssh 9.2.2.2.beta 的 Windows 2016 服务器上和安装了 open ssh for windows v 7.7.2.1 的 2019 服务器上也遇到了同样的问题

我以为这可以解决问题,但事实并非如此(我使用 chcp 命令检查它是否设置正确)https://stackoverflow.com/questions/57131654/using-utf-8-encoding-chcp-65001-in-command-prompt-windows-powershell-window/57134096#57134096

不确定为什么这在免费 ssh 中有效但在开放 ssh 中无效,或者我需要做什么来修复它。

如果我需要提供更多详细信息,请告知,非常感谢您的帮助。

额外细节:

有一个 Jenkins 服务器在 Linux 上运行,上面有一个作业,它在 Windows 机器上运行批处理文件来执行某些软件的安装。批处理文件运行一个 Python 脚本,该脚本运行一个命令,该命令会创建另一个 ssh 会话,执行此特定安装时,该会话恰好是同一服务器上的另一个用户。

为了检查它在哪个操作系统上运行,它首先假设它在 Windows 服务器上运行,并运行一个ver命令,该命令不是Microsoft Windows..返回一些垃圾字符。即:

ver_command = runw(ctx, "ver", warn=True, hide=True, echo=False)
if ver_command.ok and ver_command.stdout.lstrip().startswith('Microsoft Windows'):             // This contains garbage
    os_name = 'windows'


def runw(ctx, cmd, **kwargs):
    """ Run a remote command, assuming a remote windows (dos) environment """
    kwargs.setdefault("echo", True)
    kwargs.setdefault("shell", False)
    kwargs.setdefault("pty", True)
    return ctx.run("cmd /c " + cmd, **kwargs)

在日志文件中,执行运行命令时显示以下内容:文件“c:\python39\lib\site-packages\fabric\connection.py”,第 634 行,打开 self.client.connect(**kwargs) 文件“c:\python39\lib\site-packages\paramiko\client.py”,第 368 行,连接

对该部分进行临时硬编码后,安装作业成功完成,尽管 Jenkins 中显示的日志条目中再次出现了垃圾字符,例如 [12;1HBuilding script... [13;1H FreeSSH 不存在任何问题。

答案1

恢复 [2J 而不是 Microsoft Windows。

...

再次出现垃圾字符,例如 [12;1HBuilding script... [13;1H

Kamil Maciorowski 是正确的,那些“垃圾”字符是 ANSI 转义序列。

Esc 2 J要求您的 SSH 客户端清除屏幕并将光标移动到左上角。

Esc [ 12; 1 H要求您的 SSH 客户端将光标移动到第 12 行第 1 列。

所以这不是字符编码问题。

问题在于某些软件(可能位于服务器上)认为您的客户端是支持 ANSI 控制序列的字符模式终端(或终端仿真器)。大胆猜测,这可能是因为 OpenSSH 客户端发送了一个表明这一点的 TERM 值,而旧版 FreeSSH 没有。

我会通过尝试以下命令来诊断这个问题 ssh username@servername ver

从 Linux 系统,您可以尝试TERM=dumb ssh username@servername ver告诉服务器您的 ssh 客户端不理解 ANSI。

也可以看看https://serverfault.com/q/986847/55524


kwargs.setdefault("pty", True)正如 Kenster 在关于您的“尝试在没有 PTY 的情况下运行。PTY 用于交互式会话”的评论中指出的那样。

发出 ANSI 序列的程序通常仅在它们认为已连接到交互式终端会话时才会这样做。当连接到管道、作为计划的 cron 命令或脚本等运行时,它们不会这样做。一个典型的例子可能是ls- 其通常具有与选项 等效的默认行为-color=AUTO。诚然,我很惊讶这适用于 Microsoft Windows 的ver命令或cmdprompt

相关内容