2016-12-07 9 views
6

Pythonループで複数のバッチスクリプトを実行しようとしています。しかし、上記のバットスクリプトにはcmd /Kが含まれているため、より良い単語がないため「終了」しません。したがって、Pythonは最初のスクリプトを呼び出して、いつまでも待って...終了しないバッチスクリプトにループする

ここで私が何をしようとしていますかのアイデアを与える擬似コードです:

import subprocess 

params = [MYSCRIPT, os.curdir]  
for level in range(10): 
    subprocess.call(params) 

私の質問は:「神託がありますコンソールコマンドを元に戻してループを再開するソリューション?


編集:私は今、彼らが戻るのをしかし、これはほぼ同時に私の全体のループを発売する

Popen(params,shell=False,stdin=None,stdout=None,stderr=None,close_fds=True)

を使用して、待たずに子プロセスを起動し、継続することが可能であることを承知しています。子プロセスがそのタスクを実行し、cmd /Kに達してアイドル状態になるときに戻るまで待つ方法はありますか?

+0

OBS:誰かがなぜ私は 'cmd/K'をスクリプトから削除しないのか尋ねる前に、いくつかの理由があります。説明するのが一番簡単なことは、それらのスクリプトが私の同僚と共有されていることです。私はそれらのスクリプトを気にしたくありません。 –

+2

[この回答](http://stackoverflow.com/a/6700359/174652)のように見えます。 – joeb

+0

ありがとうございました! 'DETACHED_PROCESS'はバッチの実行を一切スキップしているようです。 'Popen'のために提案された他のオプション、すなわち' shell = True、stdin = None、stdout = None、stderr = None、close_fds = True'は非常に便利です。スクリプトは、子プロセスが終了するのを待機しません。これは、10個のスクリプトを並列スレッドとして実行する場合に非常に便利です。 しかし私は、子プロセスがタスクを実行し、 'cmd/K'に衝突してアイドル状態になるのを待つ方法を探していると思います。これはまったく可能ですか?これを反映するために質問を編集する必要がありますか? –

答えて

3

そこには方法で構築されないが、それはあなたが実装することができるものです。

私はほど簡単であるかもしれないWindowsマシンにアクセスすることはできませんが、 cmd \K

についても同様でなければなりませんので、

例としては、bashのである:これはexitコマンドを送信します

import subprocess 

# start the process in the background 
process = subprocess.Popen(
    ['bash', '-i'], 
    stdout=subprocess.PIPE, 
    stdin=subprocess.PIPE 
) 

# will throw IO error if process terminates by this time for some reason 
process.stdin.write("exit\n") 
process.wait() 

シェルが終了すると処理が終了する(\Kを効果的に取り消す)

ここでは、checの解決策が必要な場合に、より綿密な答えが得られますいくつかの出力のためのKS:

import subprocess 

# start the process in the background 
process = subprocess.Popen(
    ['bash', '-i'], 
    stdout=subprocess.PIPE, 
    stdin=subprocess.PIPE 
) 

    # Wait for the process to terminate 
    process.poll() 
    while process.returncode is None: 
     # read the output from the process 
     # note that can't use readlines() here as it would block waiting for the process 
     lines = [ x for x in process.stdout.read(5).split("\n") if x] 
     if lines: 
      # if you want the output to show, you'll have to print it yourself 
      print(lines) 
      # check for some condition in the output 
      if any((":" in x for x in lines)): 
       # terminate the process 
       process.kill() 
       # alternatively could send it some input to have it terminate 
       # process.stdin.write("exit\n") 
     # Check for new return code 
     process.poll() 

ここ合併症は、あなたが使用できる以上を読み取ろうかのように、プロセスはブロックされ、出力を読んでいます。

+0

華麗!これはちょうど必要なものです。私はアウトプットを必要としませんが、徹底していただければ幸いです。似たような問題を抱えている人に便利だと思います。 –

2

ここで私はプロセスの束(この例では2)を開始し、プログラムが終了する前に最後にそれらを待つところで使用するものです。異なる時間に特定のプロセスを待つように変更することができます(コメント参照)。この例では、1つのプロセスが%path%を出力し、もう1つがディレクトリの内容を出力します。

import win32api, win32con, win32process, win32event 

def CreateMyProcess2(cmd): 
    ''' create process width no window that runs sdelete with a bunch of arguments''' 
    si   = win32process.STARTUPINFO() 
    info = win32process.CreateProcess(
     None,  # AppName 
     cmd,  # Command line 
     None,  # Process Security 
     None,  # Thread Security 
     0,   # inherit Handles? 
     win32process.NORMAL_PRIORITY_CLASS, 
     None,  # New environment 
     None,  # Current directory 
     si)  # startup info 
    return info[0] 
# info is tuple (hProcess, hThread, processId, threadId) 

if __name__ == '__main__' : 
    handles  = [] 

    cmd = 'cmd /c "dir/w"' 
    handle = CreateMyProcess2(cmd) 
    handles.append(handle) 

    cmd = 'cmd /c "path"' 
    handle = CreateMyProcess2(cmd) 
    handles.append(handle) 

    rc = win32event.WaitForMultipleObjects(
     handles, # sequence of objects (here = handles) to wait for 
     1,  # wait for them all (use 0 to wait for just one) 
     15000) # timeout in milli-seconds 
    print rc 
    # rc = 0 if all tasks have completed before the time out 

(わかりやすくするために編集)おおよその出力:

PATH = C:\ Users \ユーザーフィリップ\ algs4 \ Javaの\ビン; C:\ Users \ユーザーフィリップ\ビン; C:\ Users \ユーザーフィリップ\ mksnt \ etc ......

ドライブCのボリュームにはラベルがありません。 ボリュームシリアル番号は、Cの4CA0-FEAD
ディレクトリです:[。] \ Users \ユーザーフィリップ\のAppData \ローカル\ Tempに

[..]
FXSAPIDebugLogFile.txt
など....
無料305473040384のバイト0バイト
3のDir(S)(S)ファイル - "RC" の値

+0

興味深い答えは、 ですが、ユーザーがランタイムを先験的に評価しなければならないという明らかな制限があります。 私はわずかに異なるアプローチを試みましたが、その時点で1つのハンドルを実行しています 'handle = CreateMyProcess2(cmd); rc = win32event.WaitForSingleObject(handle、30000) ' しかし、Windowsが理解できる' cmd'文字列に 'subprocess.call'引数を配置できませんでした。それを呼び出さずに 'subprocess'オブジェクトを作成してハンドルに変換する方法はありますか? –

+0

2147483647を使用できます。 – Marichyasana

+0

どういう意味ですか? 2147483647は何ですか? –

関連する問題