Python subprocess
Pythonããã³ãã³ããæãã¢ã¸ã¥ã¼ã«ãsubprocessã®ä½¿ãæ¹ãæ´çãã¦ã¿ããååã¯ããã¥ã¢ã«ããªãã£ã¦ãã http://docs.python.org/library/subprocess.html subprocessã¯os.system, os.spawn, os.popen, popen2, commandsãªã©ã®ã¢ã¸ã¥ã¼ã«ã«åã£ã¦ä»£ãä½ç½®ä»ãã ã¨ã¯ç¥ããªãã£ããããã¥ã¢ã«ã¯èªãã§ã¿ããã®ã ãã³ã¼ãã¯replã«ã³ããããã¨(UnixçOSãªã)åãã¯ãã
æºå
import sys,os
from subprocess import *
ã³ãã³ãããã®åºåãæãã
- æ¨æºåºåãæ¨æºã¨ã©ã¼åºåã¯communicate()ã§
- perlã ã¨`cmd args`
output,_=Popen(['/bin/ls', '/etc/hosts'], stdout=PIPE).communicate()
print [output]
['/etc/hosts\n']
ã³ãã³ããéå§ãPIDãå¾ã
- os.spawnlp(os.P_NOWAIT, cmd, *argv)ã®ä»£ç¨
- åããã»ã¹çµäºãå¾ ããªã
- åããã»ã¹ã¯ã·ã°ãã«ã§å¶å¾¡ã§ãã (ãã³ãã³ãã«ã·ã°ãã«ãéãããåç §)
ç´ã«pidãè¿ã£ã¦ããã
pid=Popen(['/bin/sleep', '3']).pid
print pid
ã³ãã³ããèµ°ããã¦ã¹ãã¼ã¿ã¹ãå¾ã
- åæã§(åããã»ã¹ã®çµäºãå¾ ã£ã¦)çµäºã¹ãã¼ã¿ã¹ãå¾ãã¨ãã¯call()
- æ£å¸¸çµäºã®ã¨ãã¯0ã0以ä¸ã ã¨åããã®ã·ã°ãã«å¤ã«-1ãããããã®ã
- retcode = os.spawnlp(os.P_WAIT, cmd, *argv)ã®è¿ä»£ç
3ç§ãã£ã¦ããã¹ãã¼ã¿ã¹(æåãªã0)ãè¿ãã
retcode=call(['/bin/sleep', '3'])
print retcode
0
ç°å¢å¤æ°ãã³ãã³ãã«æ¸¡ã
- Popen(.., env={}, ..)
print Popen(['/bin/echo $HOGE'],
shell=True,
env={'HOGE' : 'oh hai'},
stdout=PIPE,
stderr=PIPE).communicate()
('oh hai\n', '')
ãã¤ãã©ã¤ã³ï¼ Popenãè¤æ°éãã¦stdoutãæ¬¡ã®stdinã«ç¹ãã
- du -sk * | sort -nr ãpythonã§ãã
- c1=Popen(.. stdout=PIPE ..); c2=Popen(.. stdin=c1.stdou ..)
du=Popen(['du -sk *'], stdout=PIPE, shell=True, cwd='.')
sort=Popen(['sort', '-nr'], stdin=du.stdout, stdout=PIPE)
du.stdout.close()
out,_=sort.communicate()
print out
ã³ãã³ãã®stdinã«æ¸ãè¾¼ã
- cmd=Popen(.., stdin=PIPE, ..)ã¨éããcmd.stdinã«æ¸ãè¾¼ã
- pipe = os.popen("cmd", 'w', ..)ã®ä»£ç¨
pipe=Popen(['/usr/bin/wc', '-l'], stdin=PIPE).stdin
for n in range(10):
pipe.write('%d\n' % n)
pipe.close()
親ããã»ã¹ã®æ¨æºåºåã«10ã¨åºãã
ã³ãã³ãããã®åºåãèªã¿åºã
- cmd=Popen(.. stdout=PIPE, ..)ã¨éãã¦ã cmd.stdoutããèªã
- communicateã¯åºåãå ¨é¨ãä¸åº¦ã«è¿ã£ã¦ããã®ã§ãã¼ã¿éãã¡ã¢ãªã§å¶éããã
- ããã¯ã¹ããªã¼ã ããã¡ãã£ã¥ã¤èªããã®ã§ãå¶éãåããªã
æ¨æºåºåã«ãã¡ã¤ã«ãããªã³ãããããæ¨æºã¨ã©ã¼ã¯ãã®ã¾ã¾ç¶æ¿ãããã
pipe=Popen(['/usr/bin/find', '/etc/'], stdout=PIPE).stdoutfor line in pipe.readlines():
print line.strip()pipe.close()
stderrã¨stdoutãä¸ç·ã«åã
- Popen(.. stderr=STDOUT, .. )
- os.popen4ã¨ä¼¼ã¦ããã
print Popen(['/bin/ls', '/etc/hosts', 'nonexistant'],
stdin=PIPE, stdout=PIPE, stderr=STDOUT).communicate()
('/bin/ls: cannot access nonexistant: No such file or directory\n/etc/hosts\n', None)
ããããã¨ãstdoutã¨stderrã®åºåãå¥ããã
print Popen(['/bin/ls', '/etc/hosts', 'nonexistant'],
stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate()
('/etc/hosts\n', '/bin/ls: cannot access nonexistant: No such file or directory\n')
ã³ãã³ãã«ã·ã°ãã«ãéã
- .wait() .retcodeã§ã³ãã³ããåããã·ã°ãã«ãã¢ã¯ã»ã¹ãã
import signalp=Popen(['/bin/sleep', '9999'])
p.kill()
print p.wait()==-1*signal.SIGKILL
print p.returncode==-1*signal.SIGKILL
True
True
p=Popen(['/bin/sleep', '9999'])
p.send_signal(signal.SIGHUP)
print p.wait()==-1*signal.SIGHUP
True
stdoutã¨stderrã®ä¸¡æ¹ãèªã¿è¾¼ãã¨ãã¯communicate()ã§
ãã ãã䏿°ã«ããã¡ã¼ã«èªã¿è¾¼ãã®ã§ãã¼ã¿éãå¶éãããã
stdoutã¨stderrã®ä¸¡æ¹ãèªããã¨ãã¦ãããããã¯ããå ´åã¯è§£æ¶ã§ããã
(stdout,stderr)ãtupleã¨ãã¦è¿ã£ã¦ããã
('OH HAI', '')
print Popen(['/bin/cat'], stdout=PIPE, stderr=PIPE, stdin=PIPE).communicate('OH HAI')
stdoutã¨stderrã®ä¸¡æ¹ãèªããã¨ãã¦ãããããã¯ããä¾
ä¾ã¨ãã¦ãããããã¯ãèµ·ããããããã«stderrãå ã«èªãã§ããããããæ®éã®ã¦ã¼ã¶ã§èµ°ãããã¨ãããããã¯ããå¯è½æ§ãé«ããstderrã®ããã¡ããã£ã±ãã«ãªã£ã¦ãã³ãã³ããæ¢ã£ã¦ãã¾ãããã ãä¸è¬çã«è¤æ°ã®ããããã³ã°IOãããã¨ãã¯selectãªã©ã§ããããã¯ãããªããã¨ã確èªããªãããã£ãæ¹ãç¡é£ã ã
交äºã«èªãã§ããããããã¯ããã®ã¯åãã
# æ³¨ï¼ ãããããã¯ããã¡ãªãããã
find=Popen(['/usr/bin/find', '/'], stdout=PIPE, stderr=PIPE)for line in find.stderr.readlines():
passfor line in find.stdout.readlines():
pass
# æ³¨ï¼ ãããããã¯ããã¡ãªèªã¿ãã
while True:
print find.stderr.readline()
print find.stdout.readline()
select(2)ã使ã£ã¦stdoutã¨stderrãå¤éIOããåç´ãªä¾
- select(2)ã§ãã¼ã¿ããããã¨ã確èªãã¦ããèªããã¨ã«ãããããã¯ãé¿ãã
- çµäºå¦çç¡ã
import select
find=Popen(['/usr/bin/find', '/usr/local'], stdout=PIPE, stderr=PIPE)while True:
# 注æï¼ ãã¼ã¿çµäºã®ç¢ºèªããã¦ããªãã®ã§ãã®ã¾ã¾ã ã¨ç¡éã«ã¼ãã«å ¥ã£ã¦ãã¾ãã
rready, _, _=select.select([find.stdout, find.stderr], [ ], [ ])
if find.stdout in rready:
print find.stdout.readline().strip()
if find.stderr in rready:
print find.stderr.readline().strip()
select(2)ã§stdoutã¨stderrãå¤éIOãã
- EOF確èªä»ã
import select
find=Popen(['/usr/bin/find', '/etc'], stdout=PIPE, stderr=PIPE)rfhd=dict(out=find.stdout, err=find.stderr)
while True:
if not rfhd:
break # èªã¿è¾¼ããfdãç¡ããå ¥åãã¼ã¿ã®çµäºãrready, _, _=select.select(rfhd.values(), [ ], [ ])
for name,fh in rfhd.items():
# ãããã¯ããªãããã«ãã¼ã¿ãããfdããã ãèªãã
if fh in rready:
line=fh.readline()
# EOFãããããã¢ãã¿ã¼ãããã¡ã¤ã«ããåé¤ããã
# pythonã¯EOFã''ã§è¿ããNoneã®æ¹ãåããæãæ°ããããâ¦
if line=='':
fh.close()
del rfhd[name]
else:
print name, line.strip()
ãã³ããããã³ã°IOã§stdoutã¨stderrã®ä¸¡æ¹ããèªã
# æ®éã¦ã¼ã¶ã ã¨æ¨©éãç¡ãã¨ã©ã¼ãåºã
cmd=Popen(['/usr/bin/find', '/etc'], stdout=PIPE, stderr=PIPE)# stderrãnonblockingã«ãããstdoutã¯ãã®ã¾ã¾(blocking)
set_nonblocking(cmd.stderr)while True:
# åããã»ã¹ãstderrã§è©°ã£ã¦æ¢ã£ã¦ãã¾ããã¨ã¯ç¡ãã®ã§ãstdoutã¯ãããã¯ããªãã¯ãã
line=cmd.stdout.readline()
if line=='': # eof
break
print line.strip()# stderrï¼ nonblockingã¢ã¼ãã®èªã¿è¾¼ã¿
# nonblockingã¢ã¼ãã®fdããèªããã¨ããã¨ãEAGAIN(ä»ãã¼ã¿ç¡ãããã¾ãå¾ã§ãã£ã¦ã¿ã¦)ã¨ããã¨ã©ã¼
# ãè¿ã£ã¦ãããããã¯ç¡è¦ãã¦ããã以å¤ã®ä¾å¤ã¯æããã
try:
line=cmd.stderr.readline()
except IOError, e:
if e.args[0]==11: # EAGAIN
line=None
else:
raise
if line:
print 'stderr:', line.strip()
def set_nonblocking(fh):
""" ãã¡ã¤ã«ãã³ãã«ãnonblockingã«ãã """import fcntl
fd = fh.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)