2017-05-02 7 views
0

を別のものを開始します。サブプロセス:このプログラムはすぐに睡眠のPIDをエコーする必要があり、バックグラウンドでプロセスを開始し、1回の呼び出しで

import subprocess 
subprocess.check_output("sleep 1 & echo $!", shell=True) 

が直接シェルでこれを実行すると、それはすぐにPIDを出力しますが、Pythonでそれを実行していますechoが実行されるまでには、&は無視され、1秒かかる。

check_output(またはsubprocessの別の機能)を1回だけ実行するにはどうすればよいですか?

閉じてsleepあまりにもそれらを持っているために、出力パイプ用

答えて

1

check_output待機し(これは簡単な例で、代わりにsleep 1の現実に私は自分自身の実行ファイルを置くところ)。すぐに戻るために/dev/nullにリダイレクトすることができます。

subprocess.check_output("sleep 1 >/dev/null 2>&1 & echo $!", shell=True) 

UPDATE

その本当にバックグラウンドで実行されなかったsleep 1はので、私は少し大きめのテストを書いたかどうか言うのは難しいです。

test.pyは - 5秒

import time 

for i in range(5): 
    print(time.strftime('%H:%M:%S'), flush=True) 
    time.sleep(1) 
print('done', flush=True) 

runner.pyためstdoutに時間を書き込み - ファイルへstdoutをリダイレクトするテストを実行し、ファイルを監視します。それを実行

import subprocess as subp 
import time 
import os 

# run program in background 
pid = int(subp.check_output("python3 test.py >test.out 2>&1 & echo $!", 
    shell=True)) 
print("pid", pid) 

# monitor output file 
pos = 0 
done = False 
while not done: 
    time.sleep(.1) 
    if os.stat('test.out').st_size > pos: 
     with open('test.out', 'rb') as fp: 
      fp.seek(pos) 
      for line in fp.readlines(): 
       print(line.strip().decode()) 
       done = b'done' in line 
      pos = fp.tell() 
print("test complete") 

、私はなぜそれがブロックそれはだ、

[email protected] ~/tmp $ python3 runner.py 
pid 24353 
09:32:18 
09:32:19 
09:32:20 
09:32:21 
09:32:22 
done 
test complete 
+0

アハを取得します。 Pythonがコマンドをシェル全体に送信し、シェルの出力パイプに接続すると思っていたのは奇妙です。今私がやりたいことは、実行中に私のプログラムにいくつかのシグナルを送り、すべての出力パイプをリダイレクトし、スリープをすぐに停止し、バックグラウンドで実行しないことです。どういうわけかそれを達成することはできますか? – hansaplast

+0

'sleep'はバックグラウンドで完了まで実行されました。ちょうどその1秒をスリープ状態にするのはちょっと難しいです。 60秒間行い、 'ps'を実行すると、それが表示されます。 'check_output'がpidを返すので、出力を保持したい場合は他のファイルにリダイレクトすることができます。シグナルを送信する仕組みがあります。 – tdelaney

+0

スクリプトを書く時間をとってくれてありがとう。これは確かにこれが動作することを示しています。私はちょうど(おそらくプロセスグループのIDのために)私が始めたプロセスに 'SIGINT'を送ることに固執していますが、私はその問題の別の質問を開くかもしれません – hansaplast

関連する問題