2016-04-14 15 views
0

主なスクリプトがscript.pyあるを使用した場合、次のようにscript.pyを起動するとき、私は2つのサブプロセスを実行します。終了サブプロセスのxterm

#PART ONE: 
import subprocess 

command = ["python", "first.py"] 
command2 = ["python", "second.py"] 
n = 5 
for i in range(n): 
    p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
    p2 = subprocess.Popen(command2, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
    #PART TWO: 
    while True: #or while p.returncode==None: 
     output = p.stdout.readline().strip() 
     print output 
     if output == 'stop': 
      print 'success' 
      p.terminate() 
      p2.terminate() 
      break 

だから基本的に私は停止し、両方の時にサブプロセスp版画「停止」しています。すべてが順調。私は別の端末で2つのサブプロセスを起動する点の違いで、commandcommand2にそれぞれ'xterm','-e'を追加することで、同じことを動作させようとしています。問題は現在p.stdout.readline().strip()です。pの内容にアクセスできないので、メインスクリプトscript.pyからサブプロセスを停止することはできません。 command = ['xterm','-e','python','first.py']を使用しても、出力を読み込み、「停止」が印刷されている場合は出力を終了できるように、コード(特に#2)を変更する必要がありますか?

そこで、基本的#PART ONEは今です:

#PART ONE: 
import subprocess 

command = ["xterm","-e","python", "first.py"] 
command2 = ["xterm","-e","python", "second.py"] 
n = 5 
for i in range(n): 
    p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
    p2 = subprocess.Popen(command2, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

質問は、出力を読み取ることができるように、#PART TWOを変更する方法で、プロセスは、いくつかの条件を指定した終了しました。

+0

[XY問題](http://meta.stackexchange.com/a/66378/137096)のように見えます。コンテキストを説明するようにしてください。 'xterm'を実行する代わりに(例えば、tkinterを使って)GUIを作成することを検討してください。別のターミナルで実行されているプロセスの出力を読み込むには、[名前付きパイプを使う](http://stackoverflow.com/a/11724655/4279)があります。 '.terminate()'はプロセスツリー全体を終了させないかもしれません。[Shell = Trueで始まるpythonサブプロセスを終了する方法](http://stackoverflow.com/q/4789837) – jfs

+0

@JFSebastian haha私はあなたが送られたリンクを読んでいます:しかし、私は明示的にshell = Trueをサブプロセスを使って呼んだことはありませんでした。大文字小文字の区別があるかどうか?(またはそのリンクで提案されているその他の方法) –

+0

'Popen()'呼び出しが、より多くを生成する限り、コードに 'shell = True'がないことは重要ではありません私のコメントの主なフレーズは*「プロセスツリー全体を殺す」*です。用語を理解するには:[プロセスグループ、セッションはこれを読んでください](https://www.win.tue.nl/~aeb/linux /lk/lk-10.html) – jfs

答えて

0

単純な解決策の1つは、first.pyのstdoutを一時ファイルにリダイレクトすることです。次に、stdoutのパイプではなく、そのファイルから読み込むようにpart2を変更します。

また、xtermのマニュアルページにいくつかの情報が表示される場合があります。

+0

こんにちは、ありがとう、しかし、問題は、私はxtermを使用するときにfirst.pyのstdoutへのアクセス権がもうありません –

+0

'first.py'を 'first.py >>/tmp/too'に置き換えてpart2を目的のテキストを取得したとき、またはタイムアウト時間に達するまで、/ tmp /からの読み取りを続けます。 – Sharad

0

正直なところ、私はこれをまとめたソースを覚えていませんが、あなたが言ったように、次のクラスまたはこれを変更したバージョンを使用します。私が知る限り、サブプロセスモジュールは、プロセスをスレッドの内部に置かない限り、条件付き終了を許可しません。スレッドとプロセスを同時に管理する最も簡単な方法は、それらをクラスとしてバンドルすることです。


import os,subprocess,threading 

class RunSubprocess(object): 

    def __init__(self, cmd): 
     self.cmd = cmd 
     self.process = None 
     self.stdOut,self.stdErr = None,None 

    def run(self,timeout=100): 
     def target(): 
      self.process = subprocess.Popen(self.cmd, 
              shell=True, 
              stderr=subprocess.PIPE, 
              stdout=subprocess.PIPE, 
              universal_newlines=True, 
              bufsize=4096) 
     self.stdOut, self.stdErr = self.process.communicate() 

    self.thread = threading.Thread(target=target) 
    self.thread.start() 

    ## wait        
    if timeout != None: 
     self.thread.join(timeout) 
     if self.thread.is_alive(): 
      print('The subprocess was auto-terminated due to timeout') 
      print("..."+self.process.poll()) 
      self.process.terminate() 
      self.thread.join() 

     return self.process.returncode 
    return None 

    def terminate(self): 
     if self.thread.is_alive(): 
      self.process.terminate() 
      self.thread.join() 

if __name__ == '__main__': 
    cmd = "echo '...started'; sleep 2; echo '... finished'" 
    myProcess = RunSubprocess(cmd) 

    returnCode = myProcess.run(timeout=10) 
    myProcess.terminate() 
    print(myProcess.stdOut) 

だから私はあなたが2つのスクリプトを起動するには、このクラスを変更する可能性を信じて、それが密接にリンクすることができます。

関連する問題