python子进程通信冻结

时间:2013-11-28 09:56:22

标签: python subprocess

我有以下挂起的python代码:

cmd = ["ssh", "-tt", "-vvv"] + self.common_args
cmd += [self.host]
cmd += ["cat > %s" % (out_path)]
p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate(in_string)

应该通过ssh将字符串(in_string)保存到远程文件中。

文件已正确保存但随后进程挂起。如果我使用

cmd += ["echo"] instead of
cmd += ["cat > %s" % (out_path)]

这个过程没有挂起所以我很确定我误解了沟通认为流程退出的方式。

你知道怎么写这个命令所以“cat>文件”不会让沟通挂起吗?

2 个答案:

答案 0 :(得分:1)

-tt选项分配tty,阻止子进程在.communicate()关闭p.stdin时退出EOF(忽略import pipes from subprocess import Popen, PIPE cmd = ["ssh", self.host, "cat > " + pipes.quote(out_path)] # no '-tt' p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate(in_string) )。这有效:

#!/usr/bin/env python
import os
import posixpath
import sys
from contextlib import closing

from paramiko import SSHConfig, SSHClient

hostname, out_path, in_string = sys.argv[1:] # get from command-line 

# load parameters to setup ssh connection
config = SSHConfig()
with open(os.path.expanduser('~/.ssh/config')) as config_file:
    config.parse(config_file)
d = config.lookup(hostname)

# connect
with closing(SSHClient()) as ssh:
    ssh.load_system_host_keys()
    ssh.connect(d['hostname'], username=d.get('user'))
    with closing(ssh.open_sftp()) as sftp:
        makedirs_exists_ok(sftp, posixpath.dirname(out_path))
        with sftp.open(out_path, 'wb') as remote_file:
            remote_file.write(in_string)

您可以使用paramiko - 纯Python ssh库,通过ssh将数据写入远程文件:

makedirs_exists_ok()

其中from functools import partial from stat import S_ISDIR def isdir(ftp, path): try: return S_ISDIR(ftp.stat(path).st_mode) except EnvironmentError: return None def makedirs_exists_ok(ftp, path): def exists_ok(mkdir, name): """Don't raise an error if name is already a directory.""" try: mkdir(name) except EnvironmentError: if not isdir(ftp, name): raise # from os.makedirs() head, tail = posixpath.split(path) if not tail: assert path.endswith(posixpath.sep) head, tail = posixpath.split(head) if head and tail and not isdir(ftp, head): exists_ok(partial(makedirs_exists_ok, ftp), head) # recursive call # do create directory assert isdir(ftp, head) exists_ok(ftp.mkdir, path) 函数模仿os.makedirs()

{{1}}

答案 1 :(得分:0)

cat命令挂起是有意义的。它正在等待EOF。我尝试在字符串中发送EOF但无法使其正常工作。在研究这个问题后,我找到了一个很好的模块,用于简化SSH对命令行任务的使用,例如你的cat示例。它可能不完全是您的用例所需要的,但它确实可以解决您的问题。

使用

安装fabric
pip install fabric

在名为fabfile.py的文件中放入

from fabric.api import run

def write_file(in_string, path):
    run('echo {} > {}'.format(in_string,path))

然后使用,

从命令提示符运行此命令
fab -H username@host write_file:in_string=test,path=/path/to/file