1.运行外部命令
1.要运行一个外部命令,可以采用os.system() 交互,可以使用run() 函数
import subprocess
completed = subprocess.run(['ls','-l'])
print('returncode: ',completed.returncode)
'''
命令行参数作为字符串列表传入,run() 返回一个CompletedProcess实例,它包含进程的有关信息,退出码和输出
'''
2.将shell 参数设置为true值会使得 subprocess 创建一个中间 shell 进程,由这个进程运行命令,默认情况下会直接运行命令
import subprocess
completed = subprocess.run('echo $HOME',shell=True)
print('returncode:',completed.returncode)
3.错误处理:CompletedProcess的returncode 属性是程序的退出码.调用者负责解释这个返回值.如果run()的check 参数为True 则会检测退出码. 若发生一个错误,则会产生一个CalledProcessError异常.
import subprocess
try:
subprocess.run(['false'],check=True)
except subprocess.CalledProcessError as err:
print('Error:',err)
4.捕获输出:
对于run() 启动的进程,它的标准输入和标准输出通道会被绑定到父进程的输入和输出中,这说明调用程序无法捕获命令的输出。可以通过stdout 和stderr 参数传入 PIPE 来捕获输出,以备以后处理
import subprocess
completed = subprocess.run(['ls','-l'],stdout=subprocess.PIPE)
print('returncode:',completed.returncode)
print("Have {} bytes in stdout:\n{}".format(len(completed.stdout),completed.stdout.decode('utf-8')))
import subprocess
try:
completed = subprocess.run(
'echo to stdout;echo to stderr 1>&2;exit 1',
check = True,
shell = True,
stdout = subprocess.PIPE
)
except subprocess.CalledProcessError as err:
print('ERROR:',err)
else:
print('reurncode:',completed.returncode)
print('Have {} bytes in stdout:{!r}'.format(
len(completed.stdout),
completed.stdout.decode('utf-8')
))
import subprocess
try:
completed = subprocess.run(
'echo to stdout;echo to stderr 1>&2;exit 1',
shell = True,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
)
except subprocess.CalledProcessError as err:
print('Error:',err)
else:
print("returncode:",completed.returncode)
print("Have {} bytes in stdout:{!r}".format(
len(completed.stdout),
completed.stdout.decode('utf-8')
))
print('Have {} bytes in stderr:{!r}'.format(
len(completed.stderr),
completed.stderr.decode('utf-8')
))
import subprocess
try:
output = subprocess.check_output(
'echo to stdout;echo to stderr 1>&2',
shell = True,
stderr = subprocess.STDOUT,
)
except subprocess.CalledProcessError as err:
print('Error:',err)
else:
print("Have {} bytes in output: {!r}".format(len(output),output.decode('utf-8')))
5.抑制输出:
在不能显示或捕获输出的情况下,可以使用DEVNULL 抑制输出
import subprocess
try:
completed = subprocess.run(
'echo to stdout;echo to stderr 1>&2;exit 1',
shell = True,
stdout = subprocess.DEVNULL,
stderr = subprocess.DEVNULL
)
except subprocess.CalledProcessError as err:
print('Error:',err)
else:
print("returncode:",completed.returned)
print("stdout is {!r}".format(completed.stdout))
print("stderr is {!r}".format(completed.stderr))
6.直接处理管道
import subprocess
print('read:')
proc = subprocess.Popen(
['echo',"to stdout"],
stdout = subprocess.PIPE,
)
stdout_value = proc.communicate()[0].decode('utf-8')
print("stdout:",repr(stdout_value))
import subprocess
print("write:")
proc = subprocess.Popen(
['cat','-'],
stdin = subprocess.PIPE,
)
proc.communicate('stdin: to stdin\n'.encode('utf-8'))
import subprocess
proc = subprocess.Popen(
['cat','-'],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE
)
msg = 'through stdin to stdout'.encode('utf-8')
stdout_value = proc.communicate(msg)[0].decode('utf-8')
print("pass through:",repr(stdout_value))
import subprocess
proc = subprocess.Popen(
'cat -;echo "to stderr" 1>&2',
shell = True,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
)
msg = 'through stdin to stdout'.encode('utf-8')
stdout_value,stderr_value = proc.communicate(msg)
print('pass through:',repr(stdout_value.decode('utf-8')))
print('stderr :',repr(stderr_value.decode('utf-8')))
import subprocess
proc = subprocess.Popen(
'cat -;echo "to stderr" 1>&2',
shell = True,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT,
)
msg = 'through stdin to stdout\n'.encode('utf-8')
stdout_value,stderr_value = proc.communicate(msg)
print('combined output:',repr(stdout_value.decode('utf-8')))
print('stderr value :',repr(stderr_value))