【发布时间】:2018-04-06 16:28:21
【问题描述】:
我创建了一个类方法(仅在 Linux 上运行),它通过 SSH 向远程计算机发送命令列表并使用 subprocess.Popen 返回输出:
def remoteConnection(self, list_of_remote_commands):
ssh = subprocess.Popen(["ssh", self.ssh_connection_string], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True, bufsize=0)
# send ssh commands to stdin
for command in list_of_remote_commands:
ssh.stdin.write(command + "\n")
ssh.stdin.close()
output_dict = {'stdin': list(ssh.stdin), 'stdout': list(ssh.stdout), 'stderr': list(ssh.stderr)}
return output_dict
虽然我仍在处理子进程模块,但我读过很多关于 Popen 的文章,但没有人提到关闭它(SSH Connection with Python 3.0、Proper way to close all files after subprocess Popen and communicate、https://docs.python.org/2/library/subprocess.html)所以我认为那是没问题。
但是,当在函数之外的 ipython 中对此进行测试时,我注意到变量 ssh 似乎仍然处于活动状态。我尝试关闭 ssh.stdin、ssh.stdout 和 ssh.stderr,甚至 ssh.close()、ssh.terminate() 和 ssh.kill(),但似乎没有什么可以关闭它。我想也许没关系,但我的函数会在几个月甚至几年内被多次调用,所以我不希望它每次运行时都产生一个新进程,否则我将很快用完我的最大进程限制.所以我使用 ssh.pid 来查找 PID 并使用 ps aux | grep PID 查找它,即使在完成上述所有操作后它仍然存在。
我也试过了:
with subprocess.Popen(["ssh", self.ssh_connection_string], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True, bufsize=0) as shh:
代替:
ssh = subprocess.Popen(["ssh", self.ssh_connection_string], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True, bufsize=0)
我还记得不久前使用ssh -T 解决了类似的问题,但甚至:
ssh = subprocess.Popen(["ssh", "-T", self.ssh_connection_string], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True, bufsize=0)
没用。
如果我需要的话,我确信我会找到一些关于关闭 Popen 的信息,但是为什么该进程仍然在我的计算机上打开 - 谁能帮助我了解这里发生了什么?
【问题讨论】:
-
打开
ssh与popen的连接听起来是个坏习惯,您是否查看过ssh_decorate或paramiko?
标签: python python-3.x ssh