LoginSignup
35
30

More than 5 years have passed since last update.

[Python2.7] subprocess の使い方まとめ

Last updated at Posted at 2016-11-09

概要

subprocessを使う機会が結構多いので、わからなくて調べた点をまとめます。
調査時の自分のユースケースとしてPython 2.7環境が前提だったため、本記事はPython 2.7向けになります。

基本的には以下の公式ドキュメントを参照して下さい。
17.1. subprocess — サブプロセス管理 — Python 2.7.x ドキュメント

特にPython3.5以上の場合は汎用のrun()コマンドが追加されていたりと使用方法が異なっているため、
そのまま転用せず公式を参照して下さい。
17.5. subprocess — サブプロセス管理 — Python 3.5.2 ドキュメント

インポート指定

import
import subprocess

基本的なAPI

subprocess.call

・実行時の標準出力/標準エラーは実行されたタイミングで出力される
・正常時も異常時もリターンコードを返す

実行サンプル
import subprocess

print '!!! start'

cmd = 'echo aaa'
retcode = subprocess.call(cmd.split())
print retcode

cmd = 'false'
retcode = subprocess.call(cmd.split())
print retcode

print '!!! end'
出力
aaa
!!! start
0
1
!!! end

subprocess.check_call

・実行時の標準出力/標準エラーは実行されたタイミングで出力される
・正常時にはリターンコード0を返す
・異常時には subprocess.CalledProcessError 例外を送出する

実行サンプル
import subprocess

print '!!! start'

cmd = 'echo aaa'
retcode = subprocess.check_call(cmd.split())
print retcode

cmd = 'false'
try:
    retcode = subprocess.check_call(cmd.split())
except subprocess.CalledProcessError as e:
    print e.returncode
    print e.cmd
    print e.output

print '!!! end'
出力
aaa
!!! start
0
1
['false']
None
!!! end

subprocess.check_output

・実行時の標準出力/標準エラーは実行されたタイミングで出力される
・正常時には標準出力を返す
・異常時には subprocess.CalledProcessError 例外を送出する

実行サンプル
import subprocess

print '!!! start'

cmd = 'echo aaa'
d = subprocess.check_output(cmd.split())
print d,

cmd = 'unexist_command'
try:
    d = subprocess.check_output(
            cmd.split(),
            stderr=subprocess.STDOUT,
            shell=True)
    print d,
except subprocess.CalledProcessError as e:
    print e.returncode
    print e.cmd
    print e.output,

print '!!! end'
出力
!!! start
aaa
127
['unexist_command']
/bin/sh: unexist_command: command not found
!!! end

subprocess.check_output 使用時に標準エラーを取得する

以下のように、stderr=subprocess.STDOUT を指定する。

使用例
    d = subprocess.check_output(
            cmd.split(),
            stderr=subprocess.STDOUT,
            shell=True)

subprocessの実行ディレクトリを変更する

cwd オプションの使用

実行ディレクトリの指定
subprocess.call(cmd, cwd=workdir)

実行例を以下に示す。

実行サンプル
import subprocess

d1 = subprocess.check_output(['pwd'])                   # 初期位置 /tmp
d2 = subprocess.check_output(['pwd'], cwd='/tmp/hoge')  # 絶対パスでの確認
d3 = subprocess.check_output(['pwd'])                   # 他の移動の影響は受けない
d4 = subprocess.check_output(['pwd'], cwd='./hoge')     # 相対パスでの確認

print 'case 1:'
print d1,
print d2,

print 'case 2:'
print d3,
print d4,
実行例
case 1:
/tmp
/tmp/hoge
case 2:
/tmp
/tmp/hoge

python subprocess changing directory - Stack Overflow

注意点

実行コマンドを外部から取り込む場合、特に shell=True を指定している場合は、コマンド注入攻撃をされる場合が想定されるため、セキュリティには十分注意すること

補足:コマンド注入攻撃 / Shell Injection

IPA ISEC セキュア・プログラミング講座:Webアプリケーション編 第6章 入力対策:コマンド注入攻撃対策
Code injection - Wikipedia

不明な動作

check_outputshell=Trueを指定した場合に、標準出力/標準エラーが取得できない場合がある。(空文字列が返る)

参考

Python の subprocess で出力を受け取るときは communicate() を使おう - Qiita
pythonでコマンド実行するには - それマグで!

35
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
30