0

私のコードはこのpopen呼び出しでハングしているようです

command = "ls"
commandList = shlex.split(command)
print("Executing " + command +"\n")
print(commandList)
output = "#" * 10 + "\n" + server.name + "\n\n"
process = subprocess.Popen(
    command,
    shell=True,
    stdin=subprocess.PIPE, 
    stdout=subprocess.PIPE)
output = process.communicate()[0]
#scriptRunner.threadComplete(output)
return output

コードはのexecuteScriptOverSSHメソッドにありますSshWorker

class WorkerThread(threading.Thread):
    def __init__(self, pathToScript, server, runner):
        super(WorkerThread, self).__init__()
        self.scriptRunner = runner
        self.server = server
        self.pathToScript = pathToScript
        self.sshWorker = SshWorker.SshWorker()

    def run(self):
        print('Thread Starting')
        output = self.sshWorker.executeScriptOverSSH(
            self.server, 
            self.pathToScript)
        print('Thread Finishing!')
        self.scriptRunner.threadComplete(output)`

スレッドはへの呼び出しを通過することはありませんPopen-そこでprintステートメントを使用してチェックしました。何か案は?

4

1 に答える 1

0

以下のコードを実行しましたが、正しく動作します。「リターン コードがゼロ以外の場合は check_output barfs」とおっしゃいましたが、check_output ドキュメントを確認してください。キャッチできるCalledProcessError例外が発生し、すべてのエラーの詳細が適切な構造に含まれています。

import threading, subprocess, random, time, pprint
from subprocess import check_output

class WorkerThread(threading.Thread):
    def __init__(self, user, host, script, runner):
        super(WorkerThread, self).__init__()
        self.user = user
        self.host = host
        self.script = script
        self.runner = runner

    def run(self):
        cmd = "ssh {user}@{host} 'bash -s' < {script}".format(**self.__dict__)
        self.runner.complete(check_output(cmd, shell=True))

class Runner(object):
    def complete(self, output):
        print 'output:\n', output

WorkerThread('marwan', 'homebox', 'local_script.sh', Runner()).start()

上記のコードは、質問に投稿したのと同じ構造に従います。ただし、このアプローチを取ることはお勧めしません。以下にいくつかの提案を示します。

  • ランナーを呼び出す WorkerThread から、ランナーの詳細はわかりませんが、マルチスレッドプログラミングを行う場合、最も堅牢なスレッドセーフオプションはQueueを使用して通信することです。
  • ここで行っていることを手動で行う優れたライブラリが多数あります。それらは十分にテストされており、きれいに実行されます。paramikoも素晴らしいですし、Fabricも本当に素晴らしいです。

シンプルなファブリックのリモート実行の例

from fabric.api import run

def anonymous():
    run("uname -a")
于 2012-10-02T20:55:48.540 に答える