最後更新: 2024-01-04
目錄
- call()
- check_call(), check_output()
- shell
-
Working Directory
------------------------------------- -
Popen()
------------------------------------- - run()
介紹
subprocess 是用來取代 os.system 的 Class 來
Available In version: 2.4 and later
舊式寫法是
import os cmd = 'ls -al' os.system(cmd)
新寫法
import subprocess
cmd=['ls','-l'] # 如果有參數, 那就要用 list
myresult = subprocess.call(cmd)
print myresult # 0
call()
Usage:
subprocess.call([program, args],stdin=None, stderr=None, stdout=None,
shell=False, cwd=None, env=None, universal_newlines=False)
# Wait for command to complete, return the returncode attribute
cmd='exit 1' myresult = subprocess.call(cmd,shell=True) # return 1
* 每次 call 都是獨立的 (cd 到另一個目錄是不影響下次 call)
* env: inheriting the current process
Example:
import subprocess
cmd=['ls','-l'] # 如果有參數, 那就要用 list !!
myresult = subprocess.call(cmd)
print myresult
Output:
total 4 # shell output, 不關 print 事 !! -rwx------ 1 root root 121 Sep 23 09:13 test.py # shell output 0 # py var myresult output
* won't work: subprocess.call(['ls', '|', 'wc', '-l']) <- 用到 pipeline 時必須要有 shell
* won't work: subprocess.call('ls -l') <- subprocess is looking for an executable file called 'ls -l'
check_call(), check_output()
# 如果 return code 不是 "0" 時, 會 raise "CalledProcessError"
# CalledProcessError object 內有 "returncode" attribute
check_call vs check_output
- check_call() returns as soon as process exits
- check_output() waits until all output is read
test.py
import subprocess subprocess.check_call("exit 1")
所以有
<1> check_call()
ls_output = subprocess.check_call(['ls', '-l'])
<2> check_output()
If the return code was non-zero it raises a CalledProcessError.
>>> 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
Shell
當使用 call() 沒有 shell 時, 有些 shell features 就用唔到
such as shell pipes, filename wildcards, environment variable expansion,
and expansion of ~ to a user’s home directory.
i.e.
subprocess.call('ls | wc -l', shell=True)
subprocess.call('sleep 10', shell=True)
subprocess.call('dd if=/dev/zero of=test.bin bs=1M count=1024', shell=True)
P.S.
call() default 不會 call a system shell
Working Directory
# You set the location of the directory which you want as the working directory of the program you are launching.
# doesn't work: subprocess.call('./ls')
subprocess.call('./ls', cwd='/bin')
Popen()
Basic Usage
# Popen 比 call 好, 因為它不會等 program 完才下一行
i.e. 要等 "ls -l" 完
import subprocess subprocess.call(['ls','-l'])
相當於
import subprocess proc = Popen('ls -l') proc.wait() print proc.returncode
returncode
使用 returncode 時必須加上 wait(), 否則 returncode 只會 None
p.wait() print p.returncode
PIPE (get)
* 當用到 pipe 時, 那 script 就會等 process 完結
Popen.stdin / Popen.stdout / Popen.stderr
If the stdin/stdout/stderr argument was PIPE,
this attribute is a file object that provides input/output to the child process.
#!/usr/bin/env python import subprocess process = subprocess.Popen('ls', stdout=subprocess.PIPE, stderr=subprocess.PIPE) print process.stdout.read()
subprocess.PIPE
stdout=subprocess.PIPE, stderr=subprocess.PIPE
Special value that can be used as the stdin, stdout or stderr argument to Popen
Indicates that a pipe to the standard stream should be opened
that you can then read with the .communicate() function.
Popen.communicate(input=None)
import subprocess process = subprocess.Popen('ls', stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() print stdout
Interact with process:
* Send data to stdin (stdin=PIPE)
* Read data from stdout and stderr, until end-of-file is reached.
* Wait for process to terminate.
communicate() returns a tuple (stdoutdata, stderrdata).
* The data read is buffered in memory, so do not use this method if the data size is large.
Example: shell pipe line
output=`dmesg | grep hda`
相當於
p1 = Popen(["dmesg"], stdout=PIPE) p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) output = p2.communicate()[0]
Other Feature
Killing and dieing
proc.terminate()
proc.kill()
Other
Popen.pid
Popen.send_signal(signal)
Popen.poll() # 未行完是 None, 行完時會是 returncode
Popen.wait() # 不斷等, 最後 return returncode
subprocess.run()
The run() function was added in Python 3.5