【问题标题】:How to use sshkey with subprocess如何在子进程中使用 ssh 密钥
【发布时间】:2020-12-13 05:41:25
【问题描述】:

我正在尝试通过 ssh 连接到路由器并向 shell 写入命令。 我认为连接有效,因为我得到一个空输出而不是错误消息。我知道我必须使用密钥文件才能真正连接到设备上。也许这就是输出为空的原因。

这是我的代码:

mykey = os.path.expanduser('C:\\Users\\taaiaal1\\PycharmProjects\\hal_dmms_application\\dev_ssh')
command = 'pcb_cli -u cwmpd pcb://ipc:[/var/run/IGD] -i \'?\''

ssh = subprocess.Popen(["ssh", username + '@' + host + ':' + port, command],
                       shell=True,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
print(result)

我应该在哪里集成密钥文件?

我感觉就像检查了谷歌让我找到的每一页,即使在子进程 python 文档中我也找不到任何东西。这甚至可能吗?我正在使用 Python 3。

【问题讨论】:

标签: python ssh subprocess public-key


【解决方案1】:

一些提示:

  • 首先port:之后没有给出,它是用-p选项给出的

  • 如果需要密钥,则必须使用-i 选项指定它。确保密钥的权限为0400

  • 您将远程命令作为列表提供,并且还提供shell=True 这些在某种程度上是互斥的选项。如果您想使用 shell=True,那么您可以将命令作为单个字符串给出。

  • 如果想收集远程命令的输出,只需使用subprocess.check_output。它在内部使用 popen() 函数,但为您提供更简单的界面。不要忘记函数周围的 try/except,因为如果 ssh 本身出现问题或远程命令的退出状态不为零,它会引发异常。

您的代码可能如下所示:

try:
    out = subprocess.check_output(["ssh", "-i", "<path to your key>", "-p", "<port number>", "{}@{}".format(user, host), command])
    print(out)
except CalledProcessError as e:
    pass

如果您想了解执行远程命令的一些好的做法,请查看我的执行远程命令的implementation

PS: 有两种不同的方式使用子进程函数:一种需要 shell 来执行你的命令,例如远程命令有一个通配符(ls *.txt)或者你的远程命令例如执行uname -a 不需要shell。请查看上面的子流程文档链接。

【讨论】:

  • 是的,这很好。主机部分可以是 IP 地址或主机名,如“myserver”。对于后一种情况,名称应该在您的 /etc/hosts 文件中或通过 DNS 识别。我已经在我的答案中编辑了示例
  • 我添加了一个代理,它符合您的建议。谢谢!重要的是要知道,输出以二进制流的形式出现。转换我用output.decode('utf-8')
【解决方案2】:

使用 -i 标志指定身份文件。见ssh manual under identity_file

在你的例子中,那将是

ssh = subprocess.Popen(["ssh","-i "+mykey, username + '@' + host + ':' + port, command],
                   shell=True,
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE)

还有可用于 Python 的高级 SSH 库。

【讨论】:

    【解决方案3】:

    试试:

    ssh = subprocess.Popen(["ssh", "-i", "/path/to/key", username + '@' + host + ':' + port, command],
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    

    Popen 需要以某种方式格式化的参数数组。 获得正确 arg 表的最简单方法是这样做:

    command = "ssh -i my.key user@host"
    args = command.split(' ')
    ssh = subprocess.Popen(args)
    

    【讨论】:

      猜你喜欢
      • 2019-02-12
      • 1970-01-01
      • 1970-01-01
      • 2016-05-19
      • 2016-06-28
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 2018-05-28
      相关资源
      最近更新 更多