# 17.1. `subprocess` --- サブプロセス管理

バージョン 2.4 で追加.

`subprocess` モジュールは新しいプロセスの開始、入力/出力/エラーパイプの接続、リターンコードの取得を可能とします。このモジュールはいくつかの古いモジュールや関数を置き換えることを意図しています：

    os.system
    os.spawn*
    os.popen*
    popen2.*
    commands.*

これらの古いモジュールや関数の代わりに、 このモジュールをどのように使うかについては 古い関数を subprocess モジュールで置き換える で説明します。

参考

POSIX (Linux, BSD など) ユーザは Python 2.7 にバンドルされているバージョンよりも遥かに新しい subprocess32 モジュールをインストールして使うことを強くお勧めします。これは多くの状況においてより良い振る舞いをする差し替えです。

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

## 17.1.1. `subprocess` モジュールを使う

サブプロセスを起動するのにお奨めなのは、以下の簡易関数を使うことです。それで満足できないような高度なユースケースがあるなら、背後にある `Popen` インターフェイスを直接使ってください。

`subprocess.``call`(args, *, stdin=None, stdout=None, stderr=None, shell=False)

  args で指定された引数でコマンドを実行します。コマンドの完了を待って、 `returncode` を返します。

  ここでは引数は よく使われる引数 で説明している一番良く使うものだけ示しています (ですのでシグニチャは省略して少々変わった書き方をしています)。完全な関数シグネチャは `Popen` コンストラクタと同じです。この関数は引数を直接そのインターフェースへ渡します。

  例:

      >>> subprocess.call(["ls", "-l"])
      0

      >>> subprocess.call("exit 1", shell=True)
      1

  警告

  `shell=True` を使うことはセキュリティ上の脅威となり得ます。詳細については よく使われる引数 に含まれる警告を参照してください。

  注釈

  この関数では `stderr=PIPE` および `stderr=PIPE` を使用しないでください。子プロセスが生成する出力の大きさによってはデッドロックしうるからです。パイプが必要なのであれば `Popen` の `communicate()` メソッドを使ってください。

`subprocess.``check_call`(args, *, stdin=None, stdout=None, stderr=None, shell=False)

  指定された引数でコマンドを実行し、完了を待ちます。コマンドのリターンコードがゼロならば return しますが、そうでなければ `CalledProcessError` 例外を送出します。 `CalledProcessError` オブジェクトにはリターンコードが `returncode` 属性として収められています。

  ここでは引数は よく使われる引数 で説明している一番良く使うものだけ示しています (ですのでシグニチャは省略して少々変わった書き方をしています)。完全な関数シグネチャは `Popen` コンストラクタと同じです。この関数は引数を直接そのインターフェースへ渡します。

  例:

      >>> subprocess.check_call(["ls", "-l"])
      0

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

  バージョン 2.5 で追加.

  警告

  `shell=True` を使うことはセキュリティ上の脅威となり得ます。詳細については よく使われる引数 に含まれる警告を参照してください。

  注釈

  この関数では `stderr=PIPE` および `stderr=PIPE` を使用しないでください。子プロセスが生成する出力の大きさによってはデッドロックしうるからです。パイプが必要なのであれば `Popen` の `communicate()` メソッドを使ってください。

`subprocess.``check_output`(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)

  引数でコマンドを実行し、その出力をバイト文字列として返します。

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

  ここでは引数は よく使われる引数 で説明している一番良く使うものだけ示しています (ですのでシグニチャは省略して少々変わった書き方をしています)。完全な関数シグネチャは `Popen` コンストラクタとほぼ同じで、 stdout だけはこの関数が内部利用で使うので指定は許されません。その他の引数は `Popen` コンストラクタにそのまま渡されます。

  例:

      >>> subprocess.check_output(["echo", "Hello World!"])
      'Hello World!\n'

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

  標準エラーも結果に含めるには、`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'

  バージョン 2.7 で追加.

  警告

  `shell=True` を使うことはセキュリティ上の脅威となり得ます。詳細については よく使われる引数 に含まれる警告を参照してください。

  注釈

  この関数では `stderr=PIPE` を使用しないでください。子プロセスが生成するエラー出力の大きさによってはデッドロックしうるからです。標準エラー出力のパイプが必要なのであれば `Popen` の `communicate()` メソッドを使ってください。

`subprocess.``PIPE`

  `Popen` の stdin, stdout, stderr 引数に渡して、標準ストリームに対するパイプを開くことを指定するための特別な値.

`subprocess.``STDOUT`

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

exception `subprocess.``CalledProcessError`

  `check_call()` または `check_output()` によって実行されるプロセスが非ゼロの終了ステータスを返す場合に送出される例外です。

  `returncode`

    子プロセスの終了ステータスです。

  `cmd`

    子プロセスを spawn するために使用されるコマンドです。

  `output`

    この例外が `check_output()` によって送出された場合は子プロセスの出力です。そうでなければ `None` です。

### 17.1.1.1. よく使われる引数

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

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

> stdin, stdout および stderr には、実行するプログラムの標準入力、標準出力、および標準エラー出力のファイルハンドルをそれぞれ指定します。有効な値は `PIPE` 、既存のファイルデスクリプタ (正の整数)、既存のファイルオブジェクト、そして `None` です。 `PIPE` を指定すると新しいパイプが子プロセスに向けて作られます。デフォルト設定の `None` を指定するとリダイレクトは起こりません。子プロセスのファイルハンドルはすべて親から受け継がれます。 加えて、 stderr を `STDOUT` にすると、子プロセスの標準エラー出力からの出力は stdout と同じファイルハンドルに出力されます。

> stdout か stdout がパイプで universal_newlines が `True` の場合 `open()` 関数への `'U'` モードとして説明されている universal newlines モードで動作し、全ての行終端コードが `'\n'` に変換されます。

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

> 警告

> 信頼されていないソースからのサニタイズされていない入力を組み込んだシェルコマンドを実行すると、任意のコマンドを実行されることになるセキュリティ上の重大な欠陥 シェルインジェクション(en) に対して脆弱になります。この理由から、コマンド文字列が外部入力から構成される場合、 `shell=True` は 絶対に使うべきではありません:

>     >>> from subprocess import call
>     >>> filename = input("What file would you like to display?\n")
>     What file would you like to display?
>     non_existent; rm -rf / #
>     >>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

> `shell=False` はシェルに基づくすべての機能を無効にしますが、この脆弱性の影響を受けません; `shell=False` を動かすのに役立つヒントについては `Popen` コンストラクタのドキュメント中の注釈を参照してください。

> `shell=True` を使用する場合、シェルコマンドを構築するために使用される文字列中の空白とシェルのメタ文字を適切にエスケープするために `pipes.quote()` を使用することができます。

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

### 17.1.1.2. Popen コンストラクタ

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

class `subprocess.``Popen`(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

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

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

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

  注釈

  args を正しくトークン化するには、 `shlex.split()` が便利です。このメソッドは特に複雑な状況で活躍します:

      >>> import shlex, subprocess
      >>> command_line = raw_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) # Success!

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

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

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

  Unix で `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` は行ごとにバッファされることを、それ以外の正の値は (ほぼ) その大きさのバッファが使われることを意味します。負の bufsize はシステムのデフォルト値が使われることを意味し、通常これはバッファがすべて有効となります。 bufsize のデフォルト値は `0` (バッファされない) です。

  注釈

  パフォーマンス上の問題がある場合、 bufsize を -1 か十分大きな正の値 (例えば 4096) に設定し、バッファを有効にすることを勧めます。

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

  stdin, stdout および stderr には、実行するプログラムの標準入力、標準出力、および標準エラー出力のファイルハンドルをそれぞれ指定します。有効な値は `PIPE` 、既存のファイルデスクリプタ (正の整数)、既存のファイルオブジェクト、そして `None` です。 `PIPE` を指定すると新しいパイプが子プロセスに向けて作られます。デフォルト設定の `None` を指定するとリダイレクトは起こりません。子プロセスのファイルハンドルはすべて親から受け継がれます。 加えて、 stderr を `STDOUT` にすると、子プロセスの標準エラー出力からの出力は stdout と同じファイルハンドルに出力されます。

  preexec_fn に callable オブジェクトが指定されている場合、このオブジェクトは子プロセスが起動されてから、プログラムが exec される直前に呼ばれます。(Unixのみ)

  close_fds が true の場合、子プロセスが実行される前に `0`, `1`, `2` 以外のすべてのファイルデスクリプタが閉じられます (Unixのみ)。 Windows では close_fds が true の場合、すべてのファイルハンドルは子プロセスに引き継がれません。 Windows の場合、 close_fds を true にしながら、 stdin, stdout, stderr を利用して標準ハンドルをリダイレクトすることはできません。

  cwd が `None` 以外の場合、子プロセスのカレントディレクトリが実行される前に cwd に変更されます。このディレクトリは実行ファイルを探す段階では考慮されませんので、プログラムのパスを cwd に対する相対パスで指定することはできない、ということに注意してください。

  env が `None` 以外の場合、これは新しいプロセスでの環境変数を定義します。デフォルトでは、子プロセスは現在のプロセスの環境変数を引き継ぎます。

  注釈

  env を特定の値として与える場合、プログラムを実行するのに必要な変数全てを与えなければなりません。 Windows で side-by-side assembly を実行するためには、 env は正しい `SystemRoot` を 含まなければいけません 。

  universal_newlines を `True` にすると、ファイルオブジェクト stdout, stderr が universal newlines モードのテキストファイルとして開きます。行は Unix 慣習の `'\r\n'` 、古い Macintosh 慣習の `'\r'` 、 Windows 慣習の `'\r\n'` のいずれでも終端するでしょうが、どの外部化表現であれ Python プログラムからは `'\n'` に見えるようになります。

  注釈

  この機能は Python に universal newline がサポートされている場合 (デフォルト) にのみ有効です。また、 `stdout`, `stdin` および `stderr` のファイルオブジェクトの newlines 属性は communicate() メソッドでは更新されません。

  startupinfo は、根底の `CreateProcess` 関数に渡される `STARTUPINFO` オブジェクトになります。 creationflags は、与えられるなら、 `CREATE_NEW_CONSOLE` または `CREATE_NEW_PROCESS_GROUP` にできます。(Windows のみ)

### 17.1.1.3. 例外

子プロセス内で送出された例外は、新しいプログラムの実行開始の前に親プロセスで再送出されます。さらに、この例外オブジェクトには `child_traceback` という属性が追加されています。この属性は子プロセスの視点からの traceback 情報が格納された文字列です。

最も一般的に起こる例外は `OSError` です。これは、たとえば存在しないファイルを実行しようとしたときなどに発生します。アプリケーションは `OSError` 例外に備えておかなければなりません。

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

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

### 17.1.1.4. セキュリティ

ほかの popen 関数とは異なり、この実装は決して暗黙のうちにシステムシェルを実行しません。これはシェルのメタ文字を含むすべての文字が子プロセスに安全に渡されるということを意味しています。明らかに、シェルが明示的に起動される場合は、空白とメタキャラクターがすべて適切にクオートされていることを保証するのはアプリケーションの責任です。

## 17.1.2. Popen オブジェクト

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

`Popen.``poll`()

  子プロセスが終了しているかどうかを調べます。 `returncode` 属性を設定して返します。

`Popen.``wait`()

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

  警告

  これは、子プロセスが十分な出力を生成したのに、出力先が、 OS パイプバッファがそれ以上のデータを受け付けるのを待っているような場合に、デッドロックになります。これを避けるために、 `communicate()` を利用してください。

`Popen.``communicate`(input=None)

  プロセスと通信します: end-of-file に到達するまでデータを stdin に送信し、stdout および stderr からデータを受信します。プロセスが終了するまで待ちます。オプション引数 input には子プロセスに送られる文字列か、あるいはデータを送らない場合は `None` を指定します。

  `communicate()` はタプル `(stdoutdata, stderrdata)` を返します。

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

  注釈

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

`Popen.``send_signal`(signal)

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

  注釈

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

  バージョン 2.6 で追加.

`Popen.``terminate`()

  子プロセスを止めます。 Posix OS では、このメソッドは SIGTERM シグナルを子プロセスに送ります。 Windows では、 Win32 API の `TerminateProcess()` 関数を利用して子プロセスを止めます。

  バージョン 2.6 で追加.

`Popen.``kill`()

  子プロセスを kill します。 Posix OS では SIGKILL シグナルを子プロセスに送ります。 Windows では、 `kill()` は `terminate()` のエイリアスです。

  バージョン 2.6 で追加.

以下の属性も利用可能です:

警告

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

`Popen.``stdin`

  stdin 引数が `PIPE` の場合、この属性には子プロセスの入力に使われるファイルオブジェクトになります。そうでない場合は `None` です。

`Popen.``stdout`

  stdout 引数が `PIPE` の場合、この属性には子プロセスの出力に使われるファイルオブジェクトになります。そうでない場合は `None` です。

`Popen.``stderr`

  stderr 引数が `PIPE` の場合、この属性には子プロセスのエラー出力に使われるファイルオブジェクトになります。そうでない場合は `None` です。

`Popen.``pid`

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

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

`Popen.``returncode`

  `poll()` か `wait()` (か、間接的に `communicate()`)から設定された、子プロセスの終了ステータスが入ります。 `None` はまだその子プロセスが終了していないことを示します。

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

## 17.1.3. Windows Popen ヘルパ

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

class `subprocess.``STARTUPINFO`

  `Popen` の生成に使われる Windows STARTUPINFO 構造の部分的なサポートです。

  `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` として呼び出されたときに使われます。

### 17.1.3.1. 定数

`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.``CREATE_NEW_CONSOLE`

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

  `Popen` が `shell=True` として生成されたとき、このフラグは必ず設定されます。

`subprocess.``CREATE_NEW_PROCESS_GROUP`

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

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

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

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

注釈

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

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

以下の例では、適切な関数が `subprocess` モジュールからすでにインポートされていることを前提としています。

### 17.1.4.1. /bin/sh シェルのバッククォートを置き換える

    output=`mycmd myarg`

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

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

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

    output=`dmesg | grep hda`

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

    p1 = Popen(["dmesg"], stdout=PIPE)
    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
    p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
    output = p2.communicate()[0]

p2 を開始した後の p1.stdout.close() の呼び出しは、p1 が p2 の前に存在した場合に、p1 が SIGPIPE を受け取るために重要です。

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

    output=`dmesg | grep hda`

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

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

### 17.1.4.3. `os.system()` を置き換える

    status = os.system("mycmd" + " myarg")
    # becomes
    status = subprocess.call("mycmd" + " myarg", shell=True)

注釈:

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

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

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

### 17.1.4.4. `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"})

### 17.1.4.5. `os.popen()`, `os.popen2()`, `os.popen3()` を置き換える

    pipe = os.popen("cmd", 'r', bufsize)
    ==>
    pipe = Popen("cmd", shell=True, bufsize=bufsize, stdout=PIPE).stdout

    pipe = os.popen("cmd", 'w', bufsize)
    ==>
    pipe = Popen("cmd", shell=True, bufsize=bufsize, stdin=PIPE).stdin

    (child_stdin, child_stdout) = os.popen2("cmd", mode, bufsize)
    ==>
    p = Popen("cmd", shell=True, bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, close_fds=True)
    (child_stdin, child_stdout) = (p.stdin, p.stdout)

    (child_stdin,
     child_stdout,
     child_stderr) = os.popen3("cmd", mode, bufsize)
    ==>
    p = Popen("cmd", shell=True, bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
    (child_stdin,
     child_stdout,
     child_stderr) = (p.stdin, p.stdout, p.stderr)

    (child_stdin, child_stdout_and_stderr) = os.popen4("cmd", mode,
                                                       bufsize)
    ==>
    p = Popen("cmd", shell=True, bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
    (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

Unix では、 os.popen2、os.popen3、os.popen4 は実行するコマンドとしてシーケンスも受け入れます。どちらにせよ、引数はシェルの干渉を受けることなく直接渡されます。この使い方は以下のように置き換えられます。

    (child_stdin, child_stdout) = os.popen2(["/bin/ls", "-l"], mode,
                                            bufsize)
    ==>
    p = Popen(["/bin/ls", "-l"], bufsize=bufsize, stdin=PIPE, stdout=PIPE)
    (child_stdin, child_stdout) = (p.stdin, p.stdout)

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

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

### 17.1.4.6. `popen2` モジュールの関数群を置き換える

    (child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
    ==>
    p = Popen("somestring", shell=True, bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, close_fds=True)
    (child_stdout, child_stdin) = (p.stdout, p.stdin)

Unix では、 popen2 は実行するコマンドとしてシーケンスも受け入れます。どちらにせよ、引数はシェルの干渉を受けることなく、直接渡されます。この使い方は、以下のように置き換えられます。

    (child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize,
                                                mode)
    ==>
    p = Popen(["mycmd", "myarg"], bufsize=bufsize,
              stdin=PIPE, stdout=PIPE, close_fds=True)
    (child_stdout, child_stdin) = (p.stdout, p.stdin)

`popen2.Popen3` および `popen2.Popen4` は以下の点を除けば、基本的に `subprocess.Popen` と同じです:

- `Popen` は実行が失敗した場合に例外を送出します。

- capturestderr 引数は stderr 引数に代わりました。

- `stdin=PIPE` および `stdout=PIPE` を指定する必要があります。

- popen2 はデフォルトですべてのファイル記述子を閉じますが、 `Popen` では明示的に `close_fds=True` を指定する必要があります。

## 17.1.5. 注釈

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

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

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

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

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

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

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