如何在子进程中使用 ssh 密钥
How to use sshkey with subprocess
我正在尝试通过 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)
我应该在哪里集成密钥文件?
我想检查每一页 google 让我找到,甚至在子进程 python 文档中我也找不到任何东西。这可能吗?我正在使用 Python 3.
使用 -i 标志指定标识文件。见 ssh manual under identity_file
在你的例子中,那将是
ssh = subprocess.Popen(["ssh","-i "+mykey, username + '@' + host + ':' + port, command],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
还有高级 SSH 库可用于 Python。
尝试:
ssh = subprocess.Popen(["ssh", "-i", "/path/to/key", username + '@' + host + ':' + port, command],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Popen 需要一个以特定方式格式化的参数数组。
获得正确 arg table 的最简单方法是这样做:
command = "ssh -i my.key user@host"
args = command.split(' ')
ssh = subprocess.Popen(args)
一些建议:
首先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) 或您的远程命令不需要 shell 来执行 uname -a
。请查看上面的子流程文档 link。
我正在尝试通过 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)
我应该在哪里集成密钥文件?
我想检查每一页 google 让我找到,甚至在子进程 python 文档中我也找不到任何东西。这可能吗?我正在使用 Python 3.
使用 -i 标志指定标识文件。见 ssh manual under identity_file
在你的例子中,那将是
ssh = subprocess.Popen(["ssh","-i "+mykey, username + '@' + host + ':' + port, command],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
还有高级 SSH 库可用于 Python。
尝试:
ssh = subprocess.Popen(["ssh", "-i", "/path/to/key", username + '@' + host + ':' + port, command],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Popen 需要一个以特定方式格式化的参数数组。 获得正确 arg table 的最简单方法是这样做:
command = "ssh -i my.key user@host"
args = command.split(' ')
ssh = subprocess.Popen(args)
一些建议:
首先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) 或您的远程命令不需要 shell 来执行 uname -a
。请查看上面的子流程文档 link。