subprocess --- サブプロセス管理

ソースコード: Lib/subprocess.py


subprocess モジュールでは、新しいプロセスを生成し、その標準入力、標準出力、標準エラー出力のパイプに接続して、終了コードを取得できます。 このモジュールは、次のような古いモジュールや関数を置き換えるためのものです。

os.system
os.spawn*

subprocess モジュールでこれらのモジュールや関数を置き換える方法は、後の節で説明します。

参考

PEP 324 -- subprocess モジュールを提案している PEP

利用可能な環境: not Android, not iOS, not WASI.

このモジュールは モバイルプラットフォーム と WebAssemblyプラットフォーム をサポートしません。

subprocess モジュールの使用

サブプロセスの起動には、run() 関数で対応できる用途であればこの関数を使うことを推奨します。 より高度な用途では、下層の Popen インターフェースを直接使用できます。

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)

args で指定されたコマンドを実行します。コマンドの完了を待って、CompletedProcess インスタンスを返します。

上記の引数は、もっともよく使われるものだけ示しており、後述の よく使われる引数 で説明されています (そのためここではキーワード専用引数の表記に省略されています)。 関数の完全な使用法を説明しても大部分が Popen コンストラクターの内容と同じになります - この関数のほとんどの引数は Popen インターフェイスに渡されます。 (timeout、input、check、capture_output は除きます。 )

capture_output が真なら、標準出力と標準エラー出力を捕捉します。 この指定を使うと、内部の Popen オブジェクトは stdout と stderr の両方を PIPE に設定して自動的に作成されます。 stdout や stderr 引数は capture_output と同時には指定できません。 両方のストリームをまとめて捕捉するには、capture_output を使わず、stdout を PIPE、stderr を STDOUT に設定してください。

timeout には秒数を指定でき、内部で Popen.communicate() に渡されます。 タイムアウトすると子プロセスを強制終了させ、その終了を待ちます。 子プロセスが終了した後に TimeoutExpired 例外を再送出します。 多くのプラットフォームの API では最初のプロセス作成自体を中断できないため、少なくともプロセス作成にかかる時間が経過するまでは、タイムアウト例外が発生する保証はありません。

input 引数は Popen.communicate() に渡され、サブプロセスの標準入力に送られます。 指定する場合はバイト列にする必要がありますが、encoding または errors を指定するか text が真なら文字列にします。 この指定を使うと、内部の Popen オブジェクトは stdin を PIPE に設定して自動的に作成されるため、stdin 引数は併用できません。

check に真を指定した場合、プロセスが非ゼロの終了コードで終了すると CalledProcessError 例外が送出されます。 この例外の属性には、引数、終了コード、標準出力および標準エラー出力が捕捉できた場合に格納されます。

encoding または errors を指定するか、text が真なら、標準入力、標準出力、標準エラー出力のファイルオブジェクトをテキストモードで開きます。 その際には、指定された encoding と errors、または io.TextIOWrapper のデフォルト値を使います。 universal_newlines 引数は text と同じ意味で、後方互換性のために用意されています。 デフォルトでは、ファイルオブジェクトをバイナリモードで開きます。

env が None でない場合は、新しいプロセスの環境変数を定義するマッピングを指定します。 現在のプロセスの環境を継承するデフォルトの動作に代わり、このマッピングが使用されます。 Popen に直接渡されます。 os.environ と同様に、どのプラットフォームでも文字列から文字列へのマッピングを使用できます。 POSIX では os.environb と同様に、バイト列からバイト列へのマッピングも使用できます。

例:

>>> subprocess.run(["ls", "-l"])  # 出力を捕捉しない
CompletedProcess(args=['ls', '-l'], returncode=0)

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

>>> subprocess.run(["ls", "-l", "/dev/null"], capture_output=True)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n', stderr=b'')

Added in version 3.5.

バージョン 3.6 で変更: encoding と errors が引数に追加されました。

バージョン 3.7 で変更: universal_newlines 引数のよりわかりやすい名前として、text 引数が追加されました。capture_output 引数が追加されました。

バージョン 3.12 で変更: shell=True のときのWindowsシェル検索順序を変更しました。カレントディレクトリと %PATH% は、 %COMSPEC% と %SystemRoot%\System32\cmd.exe に置き換えられました。これにより、 cmd.exe という名前の悪意のあるプログラムをカレントディレクトリにドロップしても、動作しなくなりました。

class subprocess.CompletedProcess

run() の戻り値。プロセスが終了したことを表します。

args

プロセスを起動するときに使用された引数。1 個のリストか 1 個の文字列になります。

returncode

子プロセスの終了コード。一般に、終了ステータス 0 はプロセスが正常に終了したことを示します。

負の値 -N は子プロセスがシグナル N により中止させられたことを示します (POSIX のみ)。

stdout

子プロセスから捕捉した標準出力です。 通常はバイト列ですが、run() に encoding または errors を指定した場合や、text=True で呼び出した場合は文字列になります。 標準出力を捕捉していない場合は None です。

プロセスが stderr=subprocess.STDOUT で実行された場合、標準出力と標準エラー出力が混合されたものがこの属性に格納され、stderr は None になります。

stderr

子プロセスから捕捉した標準エラー出力です。 通常はバイト列ですが、run() に encoding または errors を指定した場合や、text=True で呼び出した場合は文字列になります。 標準エラー出力を捕捉していない場合は None です。

check_returncode()

returncode が非ゼロの場合、CalledProcessError が送出されます。

Added in version 3.5.

subprocess.DEVNULL

Popen の stdin, stdout, stderr 引数に渡して、標準入出力を os.devnull から入出力するように指定するための特殊値です。

Added in version 3.3.

subprocess.PIPE

Popen の stdin, stdout, stderr 引数に渡して、標準ストリームに対するパイプを開くことを指定するための特殊値です。Popen.communicate() に非常に有用です。

subprocess.STDOUT

Popen の stderr 引数に渡して、標準エラー出力が標準出力と同じハンドルに出力されるように指定するための特殊値です。

exception subprocess.SubprocessError

このモジュールの他のすべての例外のための基底クラスです。

Added in version 3.3.

exception subprocess.TimeoutExpired

SubprocessError のサブクラスです。子プロセスの終了を待機している間にタイムアウトが発生した場合に送出されます。

cmd

子プロセスの生成に使用されるコマンド本文。

timeout

タイムアウト秒数。

output

run() にまたは check_output() によって捕捉された場合は、子プロセスの出力となり、それ以外の場合は None となります。text=True の設定に関係なく、出力が捕捉された場合は常に bytes となります。出力がない場合は b'' の代わりに None のままになることがあります。

stdout

output の別名。stderr と対になります。

stderr

run() が捕捉した子プロセスの標準エラー出力です。 捕捉していなければ None です。 標準エラー出力を捕捉した場合、text=True の設定にかかわらず常に bytes です。 出力がなければ b'' の代わりに None のままになることがあります。

Added in version 3.3.

バージョン 3.5 で変更: 属性 stdout および stderr が追加されました。

exception subprocess.CalledProcessError

SubprocessError のサブクラスです。check_call() または check_output() 、 check=True であるときの run() 、によって実行されたプロセスが非ゼロの終了ステータスを返した場合に送出されます。

returncode

子プロセスの終了ステータスを表す整数です。 シグナルによってプロセスが終了した場合は、シグナル番号を負にした値になります。

cmd

子プロセスの生成に使用されるコマンド本文。

output

run() または check_output() によって捕捉された子プロセスの出力。捕捉されなかったら None になります。

stdout

output の別名。stderr と対になります。

stderr

run() によって捕捉された子プロセスの標準エラー出力。捕捉されなかったら None になります。

バージョン 3.5 で変更: 属性 stdout および stderr が追加されました。

よく使われる引数

幅広い使用例をサポートするために、Popen コンストラクター (とその他の簡易関数) は、多くのオプション引数を受け付けます。一般的な用法については、これらの引数の多くはデフォルト値のままで問題ありません。通常必要とされる引数は以下の通りです:

args はすべての呼び出しに必要で、文字列あるいはプログラム引数のシーケンスでなければなりません。一般に、引数のシーケンスを渡す方が望ましいです。なぜなら、モジュールが必要な引数のエスケープやクオート (例えばファイル名中のスペースを許すこと) の面倒を見ることができるためです。単一の文字列を渡す場合、shell は True でなければなりません (以下を参照)。もしくは、その文字列は引数を指定せずに実行される単なるプログラムの名前でなければなりません。

stdin, stdout and stderr specify the executed program's standard input, standard output and standard error file handles, respectively. Valid values are None, PIPE, DEVNULL, an existing file descriptor (a positive integer), and an existing file object with a valid file descriptor. With the default settings of None, no redirection will occur. PIPE indicates that a new pipe to the child should be created. DEVNULL indicates that the special file os.devnull will be used. Additionally, stderr can be STDOUT, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.

encoding または errors を指定するか、text (universal_newlines とも呼びます) が真なら、ファイルオブジェクト stdin、stdout、stderr をテキストモードで開きます。 呼び出し時に指定した encoding と errors、または io.TextIOWrapper のデフォルト値を使います。

stdin については、入力での行末文字 '\n' はデフォルトの行セパレーター os.linesep に変換されます。stdout と stderr については、出力での行末はすべて '\n' に変換されます。詳細は io.TextIOWrapper クラスのドキュメントでコンストラクターの引数 newline が None である場合を参照してください。

テキストモードを使わなければ、stdin、stdout、stderr はバイナリストリームとして開かれます。 エンコーディングや行末の変換は行いません。

バージョン 3.6 で変更: encoding と errors が引数に追加されました。

バージョン 3.7 で変更: universal_newlines の別名として、text 引数が追加されました。

注釈

ファイルオブジェクト Popen.stdin、Popen.stdout、Popen.stderr の newlines 属性は、Popen.communicate() メソッドでは更新されません。

shell が True なら、指定されたコマンドはシェルによって実行されます。あなたが Python を主として (ほとんどのシステムシェル以上の) 強化された制御フローのために使用していて、さらにシェルパイプ、ファイル名ワイルドカード、環境変数展開、~ のユーザーホームディレクトリへの展開のような他のシェル機能への簡単なアクセスを望むなら、これは有用かもしれません。しかしながら、Python 自身が多くのシェル的な機能の実装を提供していることに注意してください (特に glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser(), shutil)。

バージョン 3.3 で変更: universal_newlines が True の場合、クラスはエンコーディング locale.getpreferredencoding() の代わりに locale.getpreferredencoding(False) を使用します。この変更についての詳細は、 io.TextIOWrapper クラスを参照してください。

注釈

shell=True を使う前に セキュリティで考慮すべき点 を読んでください。

これらのオプションは、他のすべてのオプションとともに Popen コンストラクターのドキュメントの中でより詳細に説明されています。

Popen コンストラクター

このモジュールの中で、根底のプロセス生成と管理は Popen クラスによって扱われます。簡易関数によってカバーされないあまり一般的でないケースを開発者が扱えるように、 Popen クラスは多くの柔軟性を提供しています。

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, extra_groups=None, user=None, umask=-1, encoding=None, errors=None, text=None, pipesize=-1, process_group=None)

新しいプロセスで子のプログラムを実行します。POSIX においては、子のプログラムを実行するために、このクラスは os.execvpe() のような挙動を使用します。Windows においては、このクラスは Windows の CreateProcess() 関数を使用します。Popen への引数は以下の通りです。

args はプログラム引数のシーケンスか、単一の文字列または path-like object でなければなりません。デフォルトでは、args がシーケンスの場合に実行されるプログラムは args の最初の要素です。args が文字列の場合、解釈はプラットフォーム依存であり、下記に説明されます。デフォルトの挙動からの追加の違いについては shell および executable 引数を参照してください。特に明記されない限り、args をシーケンスとして渡すことが推奨されます。

警告

最も確実なのは、実行ファイルに完全なパスを指定することです。 パスの付いていない名前を PATH 上で検索するには shutil.which() を使ってください。 どのプラットフォームでも、現在の Python インタープリタをもう一度起動するには sys.executable を渡すことを推奨します。 インストール済みのモジュールを起動するには、コマンドラインの -m 形式を使ってください。

executable (または args の最初の要素) のパス解決はプラットフォームに依存します。 POSIX については os.execvpe() を参照してください。 実行ファイルのパスを解決または検索するとき、cwd はカレント作業ディレクトリを変更し、env で環境変数 PATH を変更できます。 Windows については、WinAPI の CreateProcess の引数 lpApplicationName と lpCommandLine のドキュメントを参照してください。 shell=False で実行ファイルのパスを解決または検索するとき、パスの解決・検索に使うカレント作業ディレクトリは cwd では変更できず、env で環境変数 PATH を変更することもできません。 完全なパスを使うと、こうした違いをすべて避けられます。

外部プログラムへの引数をシーケンスで渡す例です。

Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])

POSIX 上では、args が文字列の場合、その文字列は実行すべきプログラムの名前またはパスとして解釈されます。しかし、これはプログラムに引数を渡さない場合にのみ可能です。

注釈

特に複雑な場合、シェルコマンドを引数のシーケンスにどう分けるかは明らかでないかもしれません。 shlex.split() を使うと、args を適切に分割する方法を確認できます。

>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # 成功!

特に注意すべき点は、シェル内でスペースで区切られたオプション (-input など) と引数 (eggs.txt など) はリストの別々の要素になるのに対し、シェル内で (上記のスペースを含むファイル名や echo コマンドのように) クォーティングやバックスラッシュエスケープが必要なものは単一のリスト要素であることです。

Windows 上では、args がシーケンスなら Windows における引数シーケンスから文字列への変換 に記述された方法で文字列に変換されます。これは根底の CreateProcess() が文字列上で動作するからです。

バージョン 3.6 で変更: POSIX では、shell が False の場合に args 引数が path-like object、およびパス類似オブジェクトを含むシーケンスを受け付けるようになりました。

バージョン 3.8 で変更: Windows では、shell が False の場合に args 引数が path-like object、およびバイト列やパス類似オブジェクトを含むシーケンスを受け付けるようになりました。

shell 引数 (デフォルトでは False) は、実行するプログラムとしてシェルを使用するかどうかを指定します。 shell が True の場合、 args をシーケンスとしてではなく文字列として渡すことが推奨されます。

POSIX で shell=True の場合、シェルのデフォルトは /bin/sh になります。args が文字列の場合、この文字列はシェルを介して実行されるコマンドを指定します。したがって、文字列は厳密にシェルプロンプトで打つ形式と一致しなければなりません。例えば、文字列の中にスペースを含むファイル名がある場合は、クォーティングやバックスラッシュエスケープが必要です。args がシーケンスの場合には、最初の要素はコマンド名を表わす文字列として、残りの要素は追加の引数としてシェルに渡されます。つまり、以下の Popen と等価ということです:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

Windows で shell=True とすると、COMSPEC 環境変数がデフォルトシェルを指定します。Windows で shell=True を指定する必要があるのは、実行したいコマンドがシェルに組み込みの場合だけです (例えば dir や copy)。バッチファイルやコンソールベースの実行ファイルを実行するために shell=True は必要ありません。

注釈

shell=True を使う前に セキュリティで考慮すべき点 を読んでください。

bufsize は標準入力/標準出力/標準エラー出力パイプファイルオブジェクトを生成するときに open() 関数の対応する引数に渡されます:

  • 0 はバッファリングなしを意味します (読み書きは 1 回のシステムコールで行われ、要求した量より少ないデータで戻ることがあります)。

  • 1 は行バッファリングを意味します (text=True または universal_newlines=True の場合にだけ使えます)。

  • それ以外の正の整数はバッファーのおよそのサイズになることを意味します。

  • 負のサイズ (デフォルト) は io.DEFAULT_BUFFER_SIZE のシステムデフォルトが使用されることを意味します。

バージョン 3.3.1 で変更: bufsize のデフォルトが -1 になりました。 これにより、多くのコードが期待する動作に合わせ、デフォルトでバッファリングが有効になります。 Python 3.2.4 および 3.3.1 より前のバージョンでは、誤ってデフォルトが 0 になっており、バッファリングなしで要求した量より少ない読み出しが起こり得ました。 これは意図したものではなく、多くのコードが期待する Python 2 の動作とも異なっていました。

executable 引数は、実行する置換プログラムを指定します。これが必要になるのは極めて稀です。shell=False のときは、executable は args で指定されている実行プログラムを置換します。しかし、オリジナルの args は依然としてプログラムに渡されます。ほとんどのプログラムは、args で指定されたプログラムをコマンド名として扱います。そして、それは実際に実行されたプログラムとは異なる可能性があります。POSIX において、ps のようなユーティリティの中では、args 名が実行ファイルの表示名になります。shell=True の場合、POSIX において executable 引数はデフォルトの /bin/sh に対する置換シェルを指定します。

バージョン 3.6 で変更: executable 引数が POSIX で path-like object を受け付けるようになりました。

バージョン 3.8 で変更: Windows で executable 引数がバイト列と path-like object を受け付けるようになりました。

バージョン 3.12 で変更: shell=True のときのWindowsシェル検索順序を変更しました。カレントディレクトリと %PATH% は、 %COMSPEC% と %SystemRoot%\System32\cmd.exe に置き換えられました。これにより、 cmd.exe という名前の悪意のあるプログラムをカレントディレクトリにドロップしても、動作しなくなりました。

stdin, stdout and stderr specify the executed program's standard input, standard output and standard error file handles, respectively. Valid values are None, PIPE, DEVNULL, an existing file descriptor (a positive integer), and an existing file object with a valid file descriptor. With the default settings of None, no redirection will occur. PIPE indicates that a new pipe to the child should be created. DEVNULL indicates that the special file os.devnull will be used. Additionally, stderr can be STDOUT, which indicates that the stderr data from the applications should be captured into the same file handle as for stdout.

preexec_fn に呼び出し可能オブジェクトが指定されている場合、このオブジェクトは子プロセスが実行される直前 (fork されたあと、exec される直前) に子プロセス内で呼ばれます。(POSIXのみ)

警告

アプリケーション中に複数のスレッドが存在する状態で preexec_fn 引数を使用するのは**安全ではありません**。exec が呼ばれる前に子プロセスがデッドロックを起こすことがあります。

注釈

子プロセスの環境を変更する場合は、preexec_fn 内で行う代わりに env 引数を使ってください。 preexec_fn を使って子プロセスで os.setsid() や os.setpgid() を呼び出すコードは、start_new_session や process_group 引数で置き換えてください。

バージョン 3.8 で変更: サブインタープリタでは preexec_fn 引数を使えなくなりました。 サブインタープリタでこの引数を使うと RuntimeError を送出します。 この新しい制限は、mod_wsgi、uWSGI、その他の埋め込み環境に配置されたアプリケーションに影響することがあります。

close_fds が真なら、子プロセスの実行前に 0、1、2 を除くすべてのファイル記述子を閉じます。 close_fds が偽なら、ファイル記述子は ファイル記述子の継承 で説明されている継承可能フラグに従います。

Windows では close_fds が真の場合、STARTUPINFO.lpAttributeList の handle_list 要素で明示的に渡したハンドルと、標準ハンドルのリダイレクトで渡したものを除き、子プロセスはハンドルを継承しません。

バージョン 3.2 で変更: close_fds のデフォルトは、False から上記のものに変更されました。

バージョン 3.7 で変更: Windows では、標準ハンドルをリダイレクトするときの close_fds のデフォルトが False から True に変わりました。 標準ハンドルをリダイレクトするときも close_fds を True に設定できるようになりました。

pass_fds はオプションで、親と子の間で開いたままにしておくファイル記述子のシーケンスを指定します。何らかの pass_fds を渡した場合、close_fds は強制的に True になります。(POSIXのみ)

バージョン 3.2 で変更: pass_fds 引数が追加されました。

cwd が None でなければ、子プロセスを実行する前に作業ディレクトリを cwd に変更します。 cwd には文字列、バイト列、パス類似オブジェクト を指定できます。 POSIX では、実行ファイルのパスが相対パスなら、executable (または args の最初の要素) を cwd からの相対パスとして検索します。

バージョン 3.6 で変更: cwd 引数が POSIX で path-like object を受け付けるようになりました。

バージョン 3.7 で変更: cwd 引数が Windows で path-like object を受け付けるようになりました。

バージョン 3.8 で変更: cwd 引数が Windows で bytes オブジェクトを受け付けるようになりました。

restore_signals が真の場合 (デフォルト)、Python が SIG_IGN に設定したすべてのシグナルの処理を、子プロセスで exec を実行する前に SIG_DFL に戻します。 現在の対象は SIGPIPE、SIGXFZ、SIGXFSZ です (POSIX のみ)。

バージョン 3.2 で変更: restore_signals が追加されました。

start_new_session が真なら、サブプロセスを実行する前に子プロセス内で setsid() システムコールを呼び出します。

バージョン 3.2 で変更: start_new_session が追加されました。

process_group が非負の整数なら、サブプロセスを実行する前に子プロセス内で setpgid(0, value) システムコールを呼び出します。

バージョン 3.11 で変更: process_group が追加されました。

group が None でなければ、サブプロセスを実行する前に子プロセス内で setregid() システムコールを呼び出します。 指定した値が文字列なら grp.getgrnam() で検索し、gr_gid の値を使います。 整数ならそのまま渡します (POSIX のみ)。

Added in version 3.9.

extra_groups が None でなければ、サブプロセスを実行する前に子プロセス内で setgroups() システムコールを呼び出します。 extra_groups に含まれる文字列は grp.getgrnam() で検索し、gr_gid の値を使います。 整数はそのまま渡します (POSIX のみ)。

Added in version 3.9.

user が None でなければ、サブプロセスを実行する前に子プロセス内で setreuid() システムコールを呼び出します。 指定した値が文字列なら pwd.getpwnam() で検索し、pw_uid の値を使います。 整数ならそのまま渡します (POSIX のみ)。

注釈

user を指定しても、既存の補助グループへの所属は解除されません。 セキュリティ上の目的で子プロセスの所属グループを減らすには、呼び出し側で extra_groups=() も渡す必要があります。

Added in version 3.9.

umask が負でなければ、サブプロセスを実行する前に子プロセス内で umask() システムコールを呼び出します。

Added in version 3.9.

env が None でない場合は、新しいプロセスの環境変数を定義するマッピングを指定します。 現在のプロセスの環境を継承するデフォルトの動作に代わり、このマッピングが使用されます。 os.environ と同様に、どのプラットフォームでも文字列から文字列へのマッピングを使用できます。 POSIX では os.environb と同様に、バイト列からバイト列へのマッピングも使用できます。

注釈

env を指定する場合、プログラムの実行に必要な環境変数をすべて含める必要があります。 Windows で side-by-side assembly を実行するには、env に有効な %SystemRoot% を 必ず 含めてください。

encoding または errors を指定するか text が真なら、前述の よく使われる引数 のとおり、ファイルオブジェクト stdin、stdout、stderr は指定した encoding と errors を使うテキストモードで開かれます。 universal_newlines 引数は text と同じ意味で、後方互換性のために用意されています。 デフォルトでは、ファイルオブジェクトはバイナリモードで開かれます。

Added in version 3.6: encoding と errors が追加されました。

Added in version 3.7: text が、universal_newlines のより読みやすい別名として追加されました。

startupinfo を指定する場合は STARTUPINFO オブジェクトにします。 内部の CreateProcess 関数に渡されます。

creationflags には、次のフラグを 1 つ以上指定できます:

stdin、stdout、stderr に PIPE を使う場合、pipesize でパイプのサイズを変更できます。 サイズが変更されるのは、この機能に対応するプラットフォームだけです (執筆時点では Linux のみ)。 ほかのプラットフォームでは、この引数は無視されます。

バージョン 3.10 で変更: pipesize 引数が追加されました。

Popen オブジェクトは with 文によってコンテキストマネージャーとしてサポートされます: 終了時には標準ファイル記述子が閉じられ、プロセスを待機します:

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

Popen と、それを使うこのモジュールのほかの関数は、引数 executable、args、cwd、env を持つ 監査イベント subprocess.Popen を発生させます。 プラットフォームによって、args の値は単一の文字列または文字列のリストになります。

バージョン 3.2 で変更: コンテキストマネージャーサポートが追加されました。

バージョン 3.6 で変更: 子プロセスがまだ実行中の場合、Popen のデストラクタが ResourceWarning 警告を出すようになりました。

バージョン 3.8 で変更: Popen は、性能を向上させるため、一部の場合に os.posix_spawn() を使えるようになりました。 Windows Subsystem for Linux と QEMU User Emulation では、os.posix_spawn() を使う Popen コンストラクタは、プログラムが見つからないなどのエラーでも例外を送出しなくなりました。 代わりに、子プロセスが失敗し、returncode がゼロ以外の値になります。

例外

子プロセスで新しいプログラムの実行開始前に送出された例外は、親プロセスで再送出されます。

The most common exception raised is OSError. This occurs, for example, when trying to execute a non-existent file. Applications should prepare for OSError exceptions. Note that, when shell=True, OSError will be raised by the child only if the selected shell itself was not found. To determine if the shell failed to find the requested application, it is necessary to check the return code or output from the subprocess.

不正な引数で Popen が呼ばれた場合は ValueError が発生します。

呼び出されたプロセスが非ゼロのリターンコードを返した場合 check_call() や check_output() は CalledProcessError を送出します。

run() や Popen.communicate() など、timeout 引数を受け取るすべての関数とメソッドは、プロセスが終了する前にタイムアウトすると TimeoutExpired を送出します。

このモジュールで定義されたすべての例外は SubprocessError を継承しています。

Added in version 3.3: SubprocessError 基底クラスが追加されました。

セキュリティで考慮すべき点

ほかの一部の popen 関数と異なり、このライブラリは暗黙的にシステムのシェルを呼び出しません。 そのため、シェルのメタ文字を含め、すべての文字を安全に子プロセスへ渡せます。 shell=True で明示的にシェルを呼び出す場合は、シェルインジェクション の脆弱性を避けるため、アプリケーション側ですべての空白やメタ文字を適切にクォートする必要があります。 一部のプラットフォーム では、このエスケープに shlex.quote() を使えます。

Windows では、このライブラリに渡す引数にかかわらず、バッチファイル (*.bat または *.cmd) が OS によってシステムのシェル内で起動されることがあります。 その場合、Python によるエスケープが追加されないまま、シェルの規則に従って引数が解析される可能性があります。 信頼できない情報源からの引数を使って意図的にバッチファイルを起動する場合、Python に特殊文字をエスケープさせるため、shell=True を渡すことを検討してください。 詳しい議論は gh-114539 を参照してください。

Popen オブジェクト

Popen クラスのインスタンスには、以下のようなメソッドがあります:

Popen.poll()

子プロセスが終了しているかどうかを調べます。 returncode 属性を設定して返します。そうでなければ None を返します。

Popen.wait(timeout=None)

子プロセスが終了するまで待ちます。returncode 属性を設定して返します。

プロセスが timeout 秒後に終了してない場合、TimeoutExpired 例外を送出します。この例外を捕捉して wait を再試行するのは安全です。

注釈

stdout=PIPE または stderr=PIPE を使っていると、子プロセスがパイプに大量の出力を生成し、OS のパイプバッファがデータを受け入れられるようになるまで待つ状態でブロックして、デッドロックすることがあります。 パイプを使う場合は、この問題を避けるため Popen.communicate() を使ってください。

注釈

timeout が None でなく、プラットフォームが対応している場合は、イベント駆動の効率的な仕組みを使ってプロセスの終了を待ちます:

  • Linux 5.3 以降では os.pidfd_open() と select.poll() を使います。

  • macOS とその他の BSD 系 OS では select.kqueue()、KQ_FILTER_PROC、KQ_NOTE_EXIT を使います。

  • Windows では WaitForSingleObject を使います。

これらの仕組みがどれも使えなければ、ビジーループ (非ブロッキング呼び出しと短いスリープ) に切り替えます。

注釈

非同期に待機するには asyncio モジュールを使ってください。 asyncio.create_subprocess_exec を参照してください。

バージョン 3.3 で変更: timeout が追加されました

バージョン 3.15 で変更: timeout が None でなければ、Linux 5.3 以降と macOS / BSD で効率的なイベント駆動の実装を使います。

Popen.communicate(input=None, timeout=None)

プロセスと通信します。 標準入力にデータを送り、標準出力と標準エラー出力を EOF まで読み取ります。 プロセスの終了を待ち、returncode 属性を設定します。 省略可能な input 引数には子プロセスに送るデータを指定し、送るデータがなければ None にします。 ストリームをテキストモードで開いた場合、input は文字列でなければなりません。 それ以外の場合はバイト列でなければなりません。

communicate() はタプル (stdout_data, stderr_data) を返します。 ストリームをテキストモードで開いた場合、データは文字列です。 それ以外の場合はバイト列です。

子プロセスの標準入力にデータを送りたい場合は、 Popen オブジェクトを stdin=PIPE と指定して作成しなければなりません。同じく、戻り値のタプルから None ではない値を取得するためには、 stdout=PIPE かつ/または stderr=PIPE を指定しなければなりません。

timeout 秒が経過してもプロセスが終了しなければ、TimeoutExpired 例外を送出します。 この例外を捕捉して通信を再試行しても、出力は失われません。 タイムアウト後の communicate() 呼び出しに input を渡した場合の動作は未定義であり、将来はエラーになる可能性があります。

タイムアウトが発生した場合子プロセスは kill されません。したがって、適切にクリーンアップを行うために、正常に動作するアプリケーションは子プロセスを kill して通信を終了すべきです:

proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

communicate() が TimeoutExpired を送出した後に wait() を呼び出さないでください。 もう一度 communicate() を呼び出し、パイプの処理を終えて returncode 属性を設定してください。

注釈

受信したデータはメモリにバッファーされます。そのため、返されるデータが大きいかあるいは制限がないような場合はこのメソッドを使うべきではありません。

バージョン 3.3 で変更: timeout が追加されました

Popen.send_signal(signal)

signal シグナルを子プロセスに送ります。

プロセスが終了していれば何もしません。

注釈

Windows では、SIGTERM は terminate() の別名です。CTRL_C_EVENT と CTRL_BREAK_EVENT を、CREATE_NEW_PROCESS_GROUP を含む creationflags で始まった、プロセスに送れます。

Popen.terminate()

子プロセスを終了させます。 POSIX OS では、子プロセスに SIGTERM を送ります。 Windows では Win32 API の TerminateProcess() 関数を呼び出して子プロセスを終了させます。

Popen.kill()

子プロセスを kill します。POSIX OS では SIGKILL シグナルを子プロセスに送ります。Windows では、kill() は terminate() の別名です。

このクラスは、利用者が参照できるように次の属性も設定します。 これらの属性に新しい値を代入することはサポートされていません:

Popen.args

Popen に渡された引数 args です -- プログラム引数のシーケンスまたは 1 個の文字列になります。

Added in version 3.3.

Popen.stdin

stdin 引数が PIPE なら、この属性は open() が返すような書き込み可能なストリームオブジェクトです。 encoding または errors 引数を指定するか、text または universal_newlines 引数が True ならテキストストリームになり、それ以外ではバイトストリームになります。 stdin 引数が PIPE でなければ、この属性は None です。

Popen.stdout

stdout 引数が PIPE なら、この属性は open() が返すような読み取り可能なストリームオブジェクトです。 このストリームから子プロセスの出力を読み取れます。 encoding または errors 引数を指定するか、text または universal_newlines 引数が True ならテキストストリームになり、それ以外ではバイトストリームになります。 stdout 引数が PIPE でなければ、この属性は None です。

Popen.stderr

stderr 引数が PIPE なら、この属性は open() が返すような読み取り可能なストリームオブジェクトです。 このストリームから子プロセスのエラー出力を読み取れます。 encoding または errors 引数を指定するか、text または universal_newlines 引数が True ならテキストストリームになり、それ以外ではバイトストリームになります。 stderr 引数が PIPE でなければ、この属性は None です。

警告

.stdin.write, .stdout.read, .stderr.read を利用すると、別のパイプの OS パイプバッファーがいっぱいになってデッドロックが発生する恐れがあります。これを避けるためには communicate() を利用してください。

Popen.pid

子プロセスのプロセス ID が入ります。

shell 引数を True に設定した場合は、生成されたシェルのプロセス ID になります。

Popen.returncode

子プロセスの終了コードです。 初期値は None です。 poll()、wait()、communicate() の呼び出しでプロセスの終了を検出すると、returncode が設定されます。

値が None なら、直前のメソッド呼び出しの時点ではプロセスがまだ終了していなかったことを示します。

負の値 -N は子プロセスがシグナル N により中止させられたことを示します (POSIX のみ)。

shell=True の場合、終了コードにはシェル自体 (例えば /bin/sh) の終了ステータスが反映されます。 シェルはシグナルを 128+N などのコードに対応付けることがあります。 詳しくはシェルのドキュメント (例えば Bash マニュアルの Exit Status) を参照してください。

Windows Popen ヘルパー

STARTUPINFO クラスと以下の定数は、Windows のみで利用できます。

class subprocess.STARTUPINFO(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None)

Windows の STARTUPINFO 構造体を部分的にサポートし、Popen の作成に使います。 次の属性は、キーワード専用引数として渡すことで設定できます。

バージョン 3.7 で変更: キーワード専用引数のサポートが追加されました。

dwFlags

特定の STARTUPINFO の属性が、プロセスがウィンドウを生成するときに使われるかを決定するビットフィールドです:

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
hStdInput

dwFlags が STARTF_USESTDHANDLES を指定すれば、この属性がプロセスの標準入力ハンドルです。 STARTF_USESTDHANDLES が指定されなければ、標準入力のデフォルトはキーボードバッファーです。

hStdOutput

dwFlags が STARTF_USESTDHANDLES を指定すれば、この属性がプロセスの標準出力ハンドルです。 そうでなければ、この属性は無視され、標準出力のデフォルトはコンソールウィンドウのバッファーです。

hStdError

dwFlags が STARTF_USESTDHANDLES を指定すれば、この属性がプロセスの標準エラーハンドルです。 そうでなければ、この属性は無視され、標準エラー出力のデフォルトはコンソールウィンドウのバッファーです。

wShowWindow

dwFlags が STARTF_USESHOWWINDOW を指定すれば、この属性は ShowWindow 関数の nCmdShow 引数で指定された値なら、 SW_SHOWDEFAULT 以外の任意のものにできます。 それ以外の場合、この属性は無視されます。

この属性には SW_HIDE が提供されています。これは、Popen が shell=True として呼び出されたときに使われます。

lpAttributeList

STARTUPINFOEX で指定する、プロセス作成用の追加属性の辞書です。 UpdateProcThreadAttribute を参照してください。

サポートする属性:

handle_list

継承するハンドルのシーケンスです。 空でなければ close_fds を真にする必要があります。

これらのハンドルを Popen コンストラクタに渡すときは、os.set_handle_inheritable() で一時的に継承可能にしておく必要があります。 そうしないと、Windows エラー ERROR_INVALID_PARAMETER (87) を伴う OSError を送出します。

警告

マルチスレッドのプロセスでは、この機能と並行して os.system() などのすべてのハンドルを継承するプロセス作成関数を呼び出すとき、継承可能にしたハンドルが漏れ出さないように注意してください。 一時的に継承可能なハンドルを作成する標準ハンドルのリダイレクトでも同じ注意が必要です。

Added in version 3.7.

Windows の定数

subprocess モジュールは次の定数を公開しています。

subprocess.STD_INPUT_HANDLE

標準入力デバイスです。この初期値は、コンソール入力バッファ、 CONIN$ です。

subprocess.STD_OUTPUT_HANDLE

標準出力デバイスです。この初期値は、アクティブコンソールスクリーン、 CONOUT$ です。

subprocess.STD_ERROR_HANDLE

標準エラーデバイスです。この初期値は、アクティブコンソールスクリーン、 CONOUT$ です。

subprocess.SW_HIDE

ウィンドウを隠します。別のウィンドウがアクティブになります。

subprocess.STARTF_USESTDHANDLES

追加情報を保持する、STARTUPINFO.hStdInput, STARTUPINFO.hStdOutput, および STARTUPINFO.hStdError 属性を指定します。

subprocess.STARTF_USESHOWWINDOW

追加情報を保持する、 STARTUPINFO.wShowWindow 属性を指定します。

subprocess.STARTF_FORCEONFEEDBACK

プロセスの起動中に「バックグラウンドで作業中」のマウスカーソルを表示するよう指定する、STARTUPINFO.dwFlags の値です。 GUI プロセスではこれがデフォルトの動作です。

Added in version 3.13.

subprocess.STARTF_FORCEOFFFEEDBACK

プロセスの起動時にマウスカーソルを変更しないよう指定する、STARTUPINFO.dwFlags の値です。

Added in version 3.13.

subprocess.CREATE_NEW_CONSOLE

新しいプロセスが、親プロセスのコンソールを継承する (デフォルト) のではなく、新しいコンソールを持ちます。

subprocess.CREATE_NEW_PROCESS_GROUP

新しいプロセスグループが生成されることを指定する Popen creationflags パラメーターです。このフラグは、サブプロセスで os.kill() を使うのに必要です。

CREATE_NEW_CONSOLE が指定されていたら、このフラグは無視されます。

subprocess.ABOVE_NORMAL_PRIORITY_CLASS

新しいプロセスの優先度を通常より高くするよう指定する、Popen の creationflags 引数の値です。

Added in version 3.7.

subprocess.BELOW_NORMAL_PRIORITY_CLASS

新しいプロセスの優先度を通常より低くするよう指定する、Popen の creationflags 引数の値です。

Added in version 3.7.

subprocess.HIGH_PRIORITY_CLASS

新しいプロセスの優先度を高くするよう指定する、Popen の creationflags 引数の値です。

Added in version 3.7.

subprocess.IDLE_PRIORITY_CLASS

新しいプロセスの優先度をアイドル (最低) にするよう指定する、Popen の creationflags 引数の値です。

Added in version 3.7.

subprocess.NORMAL_PRIORITY_CLASS

新しいプロセスの優先度を通常にするよう指定する、Popen の creationflags 引数の値です (デフォルト)。

Added in version 3.7.

subprocess.REALTIME_PRIORITY_CLASS

新しいプロセスの優先度をリアルタイムにするよう指定する、Popen の creationflags 引数の値です。 マウス入力、キーボード入力、バックグラウンドでのディスクのフラッシュを管理するシステムスレッドの処理を妨げるため、REALTIME_PRIORITY_CLASS は原則として使わないでください。 ハードウェアと直接やり取りするアプリケーションや、割り込みを制限する必要がある短い処理を行うアプリケーションでは、このクラスが適切なこともあります。

Added in version 3.7.

subprocess.CREATE_NO_WINDOW

新しいプロセスがウィンドウを作成しないよう指定する、Popen の creationflags 引数の値です。

Added in version 3.7.

subprocess.DETACHED_PROCESS

新しいプロセスが親プロセスのコンソールを継承しないよう指定する、Popen の creationflags 引数の値です。 CREATE_NEW_CONSOLE と併用することはできません。

Added in version 3.7.

subprocess.CREATE_DEFAULT_ERROR_MODE

新しいプロセスが呼び出し元プロセスのエラーモードを継承しないよう指定する、Popen の creationflags 引数の値です。 新しいプロセスには代わりにデフォルトのエラーモードを設定します。 ハードエラーを無効にして実行するマルチスレッドのシェルアプリケーションで特に便利です。

Added in version 3.7.

subprocess.CREATE_BREAKAWAY_FROM_JOB

新しいプロセスをジョブに関連付けないよう指定する、Popen の creationflags 引数の値です。

Added in version 3.7.

古い高水準 API

Python 3.5 より前のバージョンでは、サブプロセスに対して以下の 3 つの関数からなる高水準 API が用意されていました。現在多くの場合 run() の使用で済みますが、既存の多くのコードではこれらの関数が使用されています。

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)

args で指定されたコマンドを実行します。コマンドの終了を待ち、returncode 属性を返します。

標準出力や標準エラー出力を捕捉する必要があるコードでは、代わりに run() を使ってください。

run(...).returncode

標準出力や標準エラー出力を抑制するには、DEVNULL を指定してください。

上記の引数は、よく使われるものだけ示しています。関数の全使用法は Popen コンストラクターの内容と同じになります - この関数は、このインターフェースに直接指定される timeout 以外は与えられた全引数を渡します。

注釈

この関数を使用する際は stdout=PIPE および stderr=PIPE を使用しないでください。子プロセスが OS のパイプバッファーを埋めてしまうほどの出力データを生成した場合、パイプからは読み込まれないので、子プロセスがブロックされることがあります。

バージョン 3.3 で変更: timeout が追加されました

バージョン 3.12 で変更: shell=True のときのWindowsシェル検索順序を変更しました。カレントディレクトリと %PATH% は、 %COMSPEC% と %SystemRoot%\System32\cmd.exe に置き換えられました。これにより、 cmd.exe という名前の悪意のあるプログラムをカレントディレクトリにドロップしても、動作しなくなりました。

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)

引数を指定してコマンドを実行し、完了を待ちます。 終了コードがゼロなら戻り、それ以外なら CalledProcessError を送出します。 CalledProcessError オブジェクトの returncode 属性には終了コードが入ります。 check_call() がプロセスを起動できなかった場合は、発生した例外をそのまま伝播させます。

標準出力や標準エラー出力を捕捉する必要があるコードでは、代わりに run() を使ってください。

run(..., check=True)

標準出力や標準エラー出力を抑制するには、DEVNULL を指定してください。

上記の引数は、よく使われるものだけ示しています。関数の全使用法は Popen コンストラクターの内容と同じになります - この関数は、このインターフェースに直接指定される timeout 以外は与えられた全引数を渡します。

注釈

この関数を使用する際は stdout=PIPE および stderr=PIPE を使用しないでください。子プロセスが OS のパイプバッファーを埋めてしまうほどの出力データを生成した場合、パイプからは読み込まれないので、子プロセスがブロックされることがあります。

バージョン 3.3 で変更: timeout が追加されました

バージョン 3.12 で変更: shell=True のときのWindowsシェル検索順序を変更しました。カレントディレクトリと %PATH% は、 %COMSPEC% と %SystemRoot%\System32\cmd.exe に置き換えられました。これにより、 cmd.exe という名前の悪意のあるプログラムをカレントディレクトリにドロップしても、動作しなくなりました。

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=None, timeout=None, text=None, **other_popen_kwargs)

引数でコマンドを実行し、その出力を返します。

コマンドのリターンコードが非ゼロならば CalledProcessError 例外が送出されます。CalledProcessError オブジェクトには、リターンコードが returncode 属性に、コマンドからの出力が output 属性に、それぞれ格納されています。

これは次と等価です:

run(..., check=True, stdout=PIPE).stdout

上に示したのは、よく使われる引数の一部だけです。 完全な関数シグネチャは run() とほぼ同じで、ほとんどの引数はそのまま渡されます。 run() の動作と異なる点が 1 つあります。 input=None を渡すと、親プロセスの標準入力のファイルハンドルを使わず、input=b'' (他の引数によっては input='') と同じ動作になります。

デフォルトで、この関数はデータをエンコードされたバイトとして返します。出力されたデータの実際のエンコードは起動されているコマンドに依存するため、テキストへのデコードは通常アプリケーションレベルで扱う必要があります。

This behaviour may be overridden by setting text, encoding, errors, or universal_newlines to True as described in よく使われる引数 and run().

標準エラー出力も結果に含めるには、stderr=subprocess.STDOUT を使います:

>>> subprocess.check_output(
...     "ls non_existent_file; exit 0",
...     stderr=subprocess.STDOUT,
...     shell=True)
'ls: non_existent_file: No such file or directory\n'

Added in version 3.1.

バージョン 3.3 で変更: timeout が追加されました

バージョン 3.4 で変更: キーワード引数 input が追加されました。

バージョン 3.6 で変更: encoding と errors が追加されました。 詳しくは run() を参照してください。

Added in version 3.7: text が、universal_newlines のより読みやすい別名として追加されました。

バージョン 3.12 で変更: shell=True のときのWindowsシェル検索順序を変更しました。カレントディレクトリと %PATH% は、 %COMSPEC% と %SystemRoot%\System32\cmd.exe に置き換えられました。これにより、 cmd.exe という名前の悪意のあるプログラムをカレントディレクトリにドロップしても、動作しなくなりました。

subprocess モジュールで古い関数を置き換える

この節では、 "a becomes b" と書かれているものは a の代替として b が使えるということを表します。

注釈

この節で紹介されている "a" 関数は全て、実行するプログラムが見つからないときは (おおむね) 静かに終了します。それに対して "b" 代替手段は OSError 例外を送出します。

また、要求された操作が非ゼロの終了コードを返した場合、check_output() を使用した置き換えは CalledProcessError で失敗します。その出力は、送出された例外の output 属性として利用可能です。

以下の例では、関連する関数を subprocess モジュールからインポート済みであると仮定します。

/bin/sh シェルのコマンド置換を置き換える

output=$(mycmd myarg)

これは以下のようになります:

output = check_output(["mycmd", "myarg"])

シェルのパイプラインを置き換える

output=$(dmesg | grep hda)

これは以下のようになります:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # p2 が終了したときに p1 が SIGPIPE を受け取れるようにする。
output = p2.communicate()[0]

p2 の開始後に p1.stdout.close() を呼び出すことが重要です。 これにより、p2 が p1 より先に終了したとき、p1 が SIGPIPE を受け取れるようになります。

あるいは、信頼された入力に対しては、シェル自身のパイプラインサポートを直接使用することもできます:

output=$(dmesg | grep hda)

これは以下のようになります:

output = check_output("dmesg | grep hda", shell=True)

os.system() を置き換える

sts = os.system("mycmd" + " myarg")
# 次のように置き換える。
retcode = call("mycmd" + " myarg", shell=True)

注釈:

  • このプログラムは普通シェル経由で呼び出す必要はありません。

  • call() の戻り値と os.system() の戻り値では、終了ステータスの表し方が異なります。

  • os.system() はコマンドの実行中に SIGINT と SIGQUIT シグナルを無視しますが、subprocess モジュールでは呼び出し側が別途これを行う必要があります。

より現実的な例ではこうなるでしょう:

try:
    retcode = call("mycmd" + " myarg", shell=True)
    if retcode < 0:
        print("Child was terminated by signal", -retcode, file=sys.stderr)
    else:
        print("Child returned", retcode, file=sys.stderr)
except OSError as e:
    print("Execution failed:", e, file=sys.stderr)

os.spawn 関数群を置き換える

P_NOWAIT の例:

pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

P_WAIT の例:

retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

シーケンスを使った例:

os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

環境変数を使った例:

os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

os.popen() を置き換える

終了コードハンドリングは以下のように解釈します:

pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
    print("There were some errors")
==>
process = Popen(cmd, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
    print("There were some errors")

レガシーなシェル呼び出し関数

このモジュールでは、以下のような 2.x commands モジュールからのレガシー関数も提供しています。これらの操作は、暗黙的にシステムシェルを起動します。また、セキュリティに関して上述した保証や例外処理一貫性は、これらの関数では有効ではありません。

subprocess.getstatusoutput(cmd, *, encoding=None, errors=None)

シェル中の cmd を実行して (exitcode, output) を返します。

check_output() を使って文字列 cmd をシェルで実行し、2 要素のタプル (exitcode, output) を返します。 出力のデコードには encoding と errors を使います。 詳しくは よく使われる引数 の注釈を参照してください。

出力の末尾の改行は取り除かれます。 コマンドの終了コードは、subprocess の終了コードとして解釈できます。 例を示します。

>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> subprocess.getstatusoutput('cat /bin/junk')
(1, 'cat: /bin/junk: No such file or directory')
>>> subprocess.getstatusoutput('/bin/junk')
(127, 'sh: /bin/junk: not found')
>>> subprocess.getstatusoutput('/bin/kill $$')
(-15, '')

利用可能な環境: Unix, Windows.

バージョン 3.3.4 で変更: Windows のサポートが追加されました。

Python 3.3.3 以前の (status, output) に代わり、(exitcode, output) を返すようになりました。 exitcode は returncode と同じ値です。

バージョン 3.11 で変更: encoding と errors が引数に追加されました。

subprocess.getoutput(cmd, *, encoding=None, errors=None)

シェル中の cmd を実行して出力 (stdout と stderr) を返します。

getstatusoutput() に似ていますが、終了コードは無視され、コマンドの出力のみを返します。例えば:

>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'

利用可能な環境: Unix, Windows.

バージョン 3.3.4 で変更: Windowsで利用可能になりました

バージョン 3.11 で変更: encoding と errors が引数に追加されました。

注釈

タイムアウトの動作

run()、Popen.wait()、Popen.communicate() などで timeout 引数を使う場合は、次の動作に注意してください:

  1. プロセス作成による遅延: 多くのプラットフォームの API では、最初のプロセス作成自体を中断できません。 そのため、タイムアウトを指定しても、少なくともプロセス作成にかかる時間が経過するまではタイムアウト例外が発生する保証はありません。

  2. 非常に短いタイムアウト: プロセス作成やシステムのスケジューリングには時間がかかるため、数ミリ秒などの非常に短いタイムアウトを設定すると、ほぼ直ちに TimeoutExpired 例外が発生することがあります。

Windows における引数シーケンスから文字列への変換

Windows では、 args シーケンスは以下の (MS C ランタイムで使われる規則に対応する) 規則を使って解析できる文字列に変換されます:

  1. 引数は、スペースかタブのどちらかの空白で分けられます。

  2. ダブルクオーテーションマークで囲まれた文字列は、空白が含まれていたとしても 1 つの引数として解釈されます。クオートされた文字列は引数に埋め込めます。

  3. バックスラッシュに続くダブルクオーテーションマークは、リテラルのダブルクオーテーションマークと解釈されます。

  4. バックスラッシュは、ダブルクオーテーションが続かない限り、リテラルとして解釈されます。

  5. 複数のバックスラッシュにダブルクオーテーションマークが続くなら、バックスラッシュ 2 つで 1 つのバックスラッシュ文字と解釈されます。バックスラッシュの数が奇数なら、最後のバックスラッシュは規則 3 に従って続くダブルクオーテーションマークをエスケープします。

参考

shlex

コマンドラインを解析したりエスケープしたりする関数を提供するモジュール。

posix_spawn() の使用を無効にする

Linux では subprocess はデフォルトで、安全に使える場合に fork() の代わりに vfork() システムコールを内部で使います。 これによって性能が大幅に向上します。

subprocess._USE_POSIX_SPAWN = False  # CPython の issue gh-NNNNNN を参照。

どの Python バージョンでも、この値を偽に設定して問題ありません。 対応していない古いバージョンや新しいバージョンでは、効果がありません。 この属性が存在して読み出せるとは仮定しないでください。 名前とは異なり、値が真でも対応する関数を使うとは限らず、使う可能性があることだけを示します。

これらの非公開の設定を使う必要がある場合は、その都度、問題を再現する方法を添えて issue を報告してください。 コード内のコメントから、その issue にリンクしてください。

Added in version 3.8: _USE_POSIX_SPAWN