2016-11-04 5 views
2


にコマンドを送信します。 os.system(s)またはsubsystem.call(s、...)を使用してコマンドを1ずつ実行すると、新しいシェルが毎回作成されるため、機能しません。
使用Jythonのサブプロセスは、bashシェル私はJythonのエンジンに bashシェルに<strong>以降の</strong>コマンドの数を送信する必要が

次の3つのテストは十分な縮小ではありません。

この最初のテストでは、コマンドが実行されますが、出力は最後にのみ取得されます。

def testRun1(): 
    # Actual Output 
    #  run 0 
    #  run 1 
    #  run 2 
    #  /home/usr/dir1/dir2 
    #  /home/usr/dir1 
    #  /home/usr 
    print 'All output is shown at the end...' 
    proc = subprocess.Popen('/bin/bash', 
          shell=True, 
          stdin=subprocess.PIPE, 
          stdout=subprocess.PIPE, 
          ) 
    for i in range(3): 
     print 'run ' + str(i) 
     proc.stdin.write('pwd\n') 
     proc.stdin.write('cd ..\n') 
    output = proc.communicate()[0] 
    print output 

「所望の出力が」

#  run 0 
#  /home/usr/dir1/dir2 
#  run 1 
#  /home/usr/dir1 
#  run 2 
#  /home/usr 

であるのに対し、この第二トライアウトは、私たちが望むものを提供しますが、Jythonスクリプトが中断されたときの出力のみが示されています。

def testRun2(): 
    # Weird : it is what we want, but all output is blocked until CTRL-C is pressed 
    #  run 0 
    #  /home/usr/dir1/dir2 
    #  run 1 
    #  /home/usr/dir1 
    #  run 2 
    #  /home/usr 
    proc = subprocess.Popen('/bin/bash', 
          shell=True, 
          stdin=subprocess.PIPE, 
          stdout=subprocess.PIPE, 
          ) 
    for i in range(3): 
     print 'run ' + str(i) 
     proc.stdin.write('pwd\n') 
     proc.stdin.write('cd ..\n') 
     print 'start to print output' 
     for line in proc.stdout: 
      print(line.decode("utf-8")) 
     print_remaining(proc.stdout) 
     print 'printed output' 

この最後の試行は、ストリームが閉じられたために2回目の実行でクラッシュします。

def testRun3(): 
    # This fails with error 
    # ValueError: I/O operation on closed file 
    proc = subprocess.Popen('/bin/bash', 
          shell=True, 
          stdin=subprocess.PIPE, 
          stdout=subprocess.PIPE, 
          ) 
    for i in range(3): 
     print 'run ' + str(i) 
     proc.stdin.write('pwd\n') 
     proc.stdin.write('cd ..\n') 
     output = proc.communicate()[0] 
     print output 
+0

1.なぜシェルスクリプトを記述しないとそれを実行する? 2.あなたはとにかくシェルを使って何をしていますか?何がbashはpython/jythonできないことができますか? – cdarke

答えて

0

あなたが抱えている問題は、部分的にはsubprocessと関係しています。パイプは根本的に、この仕事の間違ったIPCの仕組みです。対話型コマンドインタプリタをスクリプト制御下に置くには、となるようにしてください。pseudoterminalであり、それでも読み書きと同じくらい単純ではありません。

Python標準ライブラリには、私が気づいていない非常に最近のものを追加していない限り、擬似端末処理を行う組み込みモジュールはありません。ただし、サードパーティ製のパッケージpexpectはこれを実行できます。これは、実行しようとしていることとまったく同じです。基本的なpexpectのAPI使用

pexpect.replwrap

import pexpect 

def testRun4(): 
    proc = pexpect.spawn("/bin/bash") 
    for i in range(3): 
     proc.expect(":^[^$#]*[$#] *") 
     print("run", i) 
     proc.sendline("pwd") 
     proc.expect("^[^$#]*[$#] *") 
     print(proc.before) 
     proc.sendline("cd ..") 

は、それはセットアップに少しより複雑ですが、その後のループは整然とです:

def testRun5(): 
    proc = pexpect.replwrap.REPLWrapper(
     "/bin/bash", 
     orig_prompt="^[^$#]*[$#] *", 
     prompt_change="PS1='{}'; PS2='{}'") 

    for i in range(3): 
     print("run", i) 
     print(proc.run_command("pwd")) 
     proc.run_command("cd ..") 
+0

次にpexpectのインストール方法を見直す必要があります。現在、私はthinclient.shをjython.jarとともに使用していますが、完全なpython(pip)のインストールはありません。 私は深く潜んでいます –

+0

アドオンをインストールするのに適切な方法でお手伝いできませんモジュールはJythonに移植されていますが、 'pexpect'にはコンパイルされたコンポーネントがありません。最悪の場合、アプリケーションにコピーするだけです。 – zwol