我创建了一个类方法(这只能在Linux上运行),它通过SSH将命令列表发送到远程计算机,并使用subprocess.Popen返回输出:
<css-placeholder token="{{ placeholder_token }}">
虽然我仍然在掌握子流程模块,但我已经阅读了很多关于Popen的内容,并且没有人提到关闭它(SSH Connection with Python 3.0,Proper way to close all files after subprocess Popen and communicate,{{ 3}})所以我认为这不是问题。
然而,当在函数外部的ipython中测试它时,我注意到变量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
似乎仍然活跃。我尝试关闭ssh.stdin,ssh.stdout和ssh.stderr甚至ssh.close(),ssh.terminate()和ssh.kill()但似乎没有关闭它。我想也许这并不重要,但我的功能会被召唤好几个月甚至几年,所以我不想让它每次运行都会产生一个新的过程,否则我很快就会去用完了我的最大进程限制。所以我使用ssh.pid查找PID并使用ssh
进行查找,即使在完成上述所有操作之后它仍然存在。
我也尝试过:
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
没有工作。
我确定如果需要的话,我会找到关于关闭Popen的内容但是为什么这个过程仍然在我的计算机上打开 - 有人能帮我理解这里发生了什么吗?
答案 0 :(得分:2)
在你的情况下,你有一个僵局:
output_dict = {'stdin': list(ssh.stdin), 'stdout': list(ssh.stdout), 'stderr': list(ssh.stderr)}
主要是因为list(ssh.stdin)
永久阻止:尝试读取进程的标准输入不起作用(因为您将标准输出和错误重定向到不同的管道,所以还存在额外的风险不使用线程来消费它们)
您的意思是使用ssh.communicate
,将整个输入作为参数传递。只需:
command_input = "".join(["{}\n".format(x) for x in list_of_remote_commands])
output,error = ssh.communicate(command_input) # may need .encode() for python 3
return_code = ssh.wait()
然后
output_dict = {'stdin': list_of_commands, 'stdout': output.splitlines(), 'stderr': error.splitlines()}
我可以在特定的ssh情况下添加,使用paramiko模块更好(python paramiko ssh)并避免完全使用subprocess
。