我有一个使用子进程模块通过SSH连接到服务器的函数。
# python 3
def foo():
menu = ["1 = one.com",
"2 = two.com",
"3 = three.com"
]
for item in menu:
print(item)
choice = input("Which host?: ")
if choice == "1":
user = "users-name"
host = "one.com"
port = "22"
subprocess.Popen(['ssh', user + '@' + host, '-p', port])
elif
...
...
foo()
当我运行脚本时,它连接到服务器,但在按任意键后终止连接。它只是一种,静默地删除连接并返回在localhost上键入。
子进程是不是要处理并发连接?我只是要求它连接而不做任何其他事情。建议,提示,建议?
答案 0 :(得分:1)
可能有多个答案,但假设您的命令行,配置和凭据都是正确的并且ssh
调用本身就会成功,问题是(也是假设您的情况发生了一些变化)代码,或者如果上面的例子或多或少完整的话):
你分叉并执行ssh(这就是Popen
所做的),但你的父进程(脚本)继续运行并最终完成,当它发生时,它也会破坏它开始的孩子,从而让你失望即使您可能已经看到其他计算机的提示,也可以访问主机控制台。
如果我理解您的意图,您可以执行以下操作:
child = subprocess.Popen(['ssh', user + '@' + host, '-p', port])
child.wait()
或者只是使用另一种启动ssh
的方法,例如check_call()
,它会将控制权交给子进程并等到它完成。
希望这有帮助。
现在,当我看到上面的代码片段时,我无法拒绝提供一些未经请求的风格建议/提示,希望能让您的生活更轻松一些。我会有一个选择列表:
choices = [("one.com", "one_com_user", "one_com_port"), ...]
根据您的输入生成菜单条目...(转换为int
,例如entered
),您可以使用choices[entered]
来调用{{1}如果需要,在列表中使用相应的参数并处理ssh
/超出范围值,以及用户指定的未知值时您想要做的任何响应。
这将使您的代码更简洁(无条件子句),并且更易于阅读和维护(所有主机信息都在一个地方)。
还有一个关于IndexError
电话的问题。您可以跳过连接字符串并坚持参数列表,就像您已经做过的那样。 ssh
和..., user + '@' + host, ...
。应该(希望)与大多数..., '-l', user, host, ...
客户合作。