あいつの日誌β

あいつの日誌です。

Python - subprocess.Popen の挙動

以下の挙動を知らなくて迷宮入りするところだったので共有します。

Point1: time.sleep

time.sleep しておくと returncode 0 を取得できる

# -*- coding: utf-8 -*-
import time
import subprocess
cmd = ('ls', '/tmp')
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(0.001)
print p.poll()  # 0

time.sleep しないと検出できない

# -*- coding: utf-8 -*-
import time
import subprocess
cmd = ('ls', '/tmp')
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(0)
print p.poll()  # None

Point2: 不適切なオプションを指定しても OSError とならない

これは OSError が発生する

# -*- coding: utf-8 -*-
import subprocess
cmd = ('not_found_cmd', '/tmp')
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print 'ここまで到達しない'

実行結果

Traceback (most recent call last):
  File "popen.py", line 5, in <module>
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  File "/Users/okamura/local/python-2.7.3/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/Users/okamura/local/python-2.7.3/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

ただし第2引数以降(コマンドのオプション)が間違えている場合は OSError は起きない

# -*- coding: utf-8 -*-
import time
import subprocess
cmd = ('ls', '/hogehoge')
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(0.01)
print p.poll()  # 1

オプションの指定が間違えている場合は OSError とならないのは OS 側の挙動なのか Python の subprocess 側の挙動なのかは不明。