我有一个函数,它使用子进程模块通过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()
当我运行脚本时,它会连接到服务器,但在我按下任何键后,它会终止连接。它只是静默地断开连接,并返回到本地主机上键入内容。
子进程不能处理并发连接吗?我只是要求它连接,而不做其他任何事情。建议,提示,建议?
发布于 2018-06-11 02:23:24
这个问题可能有多个答案,但假设您的命令行、配置和凭据都是正确的,并且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]
在列表中使用相应的参数根据需要调用ssh
,并在用户指定未知值的情况下使用您想要的任何响应来处理IndexError
/超出范围的值。
这将使您的代码更简洁(没有条件子句),以及更容易阅读和维护(所有主机信息在一个地方)。
还有一个关于ssh
调用的问题。您可以跳过连接字符串,并坚持使用参数列表,否则就会这样做。..., user + '@' + host, ...
和..., '-l', user, host, ...
。应该(希望)能与大多数ssh
客户端一起工作。
https://stackoverflow.com/questions/50663859
复制相似问题