356

シェルスクリプトをもっと読みやすいPythonバージョンに移植しようとしています。元のシェルスクリプトは、バックグラウンドで「&」を使用していくつかのプロセス(ユーティリティ、モニターなど)を開始します。Pythonで同じ効果を達成するにはどうすればよいですか?Pythonスクリプトが完了したときにこれらのプロセスが停止しないようにしたいと思います。どういうわけかデーモンの概念に関係していると思いますが、簡単にこれを行う方法を見つけることができませんでした。

4

9 に答える 9

458

jkpのソリューションは機能しますが、物事を行う新しい方法 (およびドキュメントが推奨する方法) は、subprocessモジュールを使用することです。単純なコマンドの場合は同等ですが、複雑なことをしたい場合は、より多くのオプションが提供されます。

あなたのケースの例:

import subprocess
subprocess.Popen(["rm","-r","some.file"])

これはrm -r some.fileバックグラウンドで実行されます。.communicate()から返されたオブジェクトを呼び出すと、Popen完了するまでブロックされることに注意してください。バックグラウンドで実行したい場合は、そうしないでください。

import subprocess
ls_output=subprocess.Popen(["sleep", "30"])
ls_output.communicate()  # Will block for 30 seconds

こちらのドキュメントを参照してください。

また、明確化のポイント: ここで使用する「背景」は、純粋にシェルの概念です。技術的には、完了するのを待つ間、ブロックせずにプロセスを生成したいということです。ただし、ここではシェルの背景のような動作を指すために「背景」を使用しました。

于 2011-08-28T21:47:04.450 に答える
99

:この回答は、2009年に投稿されたときよりも最新ではありません。ドキュメントでsubprocessは、他の回答に示されているモジュールを使用することが推奨されています

( subprocess モジュールは、新しいプロセスを生成し、その結果を取得するためのより強力な機能を提供することに注意してください。これらの関数を使用するよりも、そのモジュールを使用することをお勧めします。)


プロセスをバックグラウンドで開始したい場合はsystem()、シェルスクリプトと同じ方法でプロセスを使用して呼び出すか、次のようにすることができspawnます。

import os
os.spawnl(os.P_DETACH, 'some_long_running_command')

(または、移植性の低いos.P_NOWAITフラグを試すこともできます)。

こちらのドキュメントを参照してください。

于 2009-07-28T19:05:23.843 に答える
54

おそらく、 「Python で外部コマンドを呼び出す方法」への回答が必要です。

最も簡単な方法は、os.system関数を使用することです。次に例を示します。

import os
os.system("some_command &")

基本的に、関数に渡すものは何でもsystem、スクリプトでシェルに渡した場合と同じように実行されます。

于 2009-07-28T19:02:59.293 に答える
37

私はここでこれを見つけました:

Windows(win xp)では、親プロセスは、longtask.pyが作業を終了するまで終了しません。これは、CGIスクリプトで必要なものではありません。問題はPythonに固有のものではなく、PHPコミュニティでも問題は同じです。

DETACHED_PROCESS 解決策は、プロセス作成フラグをwinAPIの基になるCreateProcess関数に渡すことです。pywin32をインストールした場合は、win32processモジュールからフラグをインポートできます。それ以外の場合は、自分でフラグを定義する必要があります。

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],
                       creationflags=DETACHED_PROCESS).pid
于 2012-11-27T21:19:09.710 に答える
33

subprocess.Popen()このパラメーターを使用するとclose_fds=True、生成されたサブプロセスを Python プロセス自体から切り離し、Python の終了後も実行を継続できます。

https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f

import os, time, sys, subprocess

if len(sys.argv) == 2:
    time.sleep(5)
    print 'track end'
    if sys.platform == 'darwin':
        subprocess.Popen(['say', 'hello'])
else:
    print 'main begin'
    subprocess.Popen(['python', os.path.realpath(__file__), '0'], close_fds=True)
    print 'main end'
于 2015-12-25T01:47:55.303 に答える
12

さまざまなスレッドを fork するための os モジュールの調査を開始することをお勧めします (対話型セッションを開いて help(os) を発行することにより)。関連する機能は fork と exec のいずれかです。開始方法についてのアイデアを得るために、フォークを実行する関数に次のようなものを入れます (関数は、プログラムの名前とそのパラメーターを含む引数として、リストまたはタプル 'args' を取る必要があります。新しいスレッドの stdin、out、および err を定義します):

try:
    pid = os.fork()
except OSError, e:
    ## some debug output
    sys.exit(1)
if pid == 0:
    ## eventually use os.putenv(..) to set environment variables
    ## os.execv strips of args[0] for the arguments
    os.execv(args[0], args)
于 2009-07-28T19:12:06.280 に答える