我正在尝试通过ssh连接到路由器并将命令写入外壳。 我认为连接有效,因为我得到的输出为空,而不是错误消息。我知道我必须使用密钥文件才能真正在设备上进行连接。也许这就是输出为空的原因。
这是我的代码:
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 doc中我也找不到任何东西。这有可能吗?我正在使用Python3。
答案 0 :(得分:2)
一些指针:
:
之后没有给出端口,它是通过-p
选项给出的-i
选项进行指定。确保对密钥的权限为0400
。您以列表的形式给出了远程命令,并且还以相互排斥的方式给出了shell=True
。如果要使用shell = True,则将命令作为单个字符串给出。
如果要收集远程命令的输出,只需使用subprocess.check_output。它内部使用popen()函数,但为您提供了更简单的界面。不要忘记try / except函数,因为ssh本身出错或远程命令的退出状态为非零会引发异常。
您的代码可能如下:
try:
out = subprocess.check_ouptput(["ssh", "-i", "<path to your key>", "-p", "<port number>", "{}@{}".format(user, host), command])
print(out)
except CalledProcessError as e:
...
如果要查看执行远程命令的一些良好做法,请查看我执行远程命令的implementation。
PS:有两种使用子进程功能的方式:一种需要外壳程序来执行命令,例如,如果远程命令具有通配符(ls * .txt)或您的远程命令不需要外壳程序来执行uname -a
。请查看上面的子流程文档链接。
答案 1 :(得分:0)
使用-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库。
答案 2 :(得分:0)
尝试:
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)