subprocess系统指令交互
subprocess
通过子进程来执行外部指令,并通过input/output/error
管道,获取子进程的执行的返回信息。其他类似的如os.system
、os.spawn*
、os.popen*
、commands.*
等
导入模块
import subprocess
subprocess.call()
执行命令,并返回执行状态,其中shell参数为False
时,命令需要通过列表的方式传入,当shell为True
时,可直接传入命令,执行成功返回0,失败返回1
root@StarMeow-Svr:~# df -hT
Filesystem Type Size Used Avail Use% Mounted on
udev devtmpfs 424M 0 424M 0% /dev
tmpfs tmpfs 87M 2.2M 85M 3% /run
/dev/vda1 ext3 50G 7.5G 40G 17% /
>>> a = subprocess.call(['df','-hT'],shell=False)
Filesystem Type Size Used Avail Use% Mounted on
udev devtmpfs 424M 0 424M 0% /dev
tmpfs tmpfs 87M 2.2M 85M 3% /run
/dev/vda1 ext3 50G 7.5G 40G 17% /
>>> a
0
>>> a = subprocess.call('df -hT',shell=True)
Filesystem Type Size Used Avail Use% Mounted on
udev devtmpfs 424M 0 424M 0% /dev
tmpfs tmpfs 87M 2.2M 85M 3% /run
/dev/vda1 ext3 50G 7.5G 40G 17% /
>>> a
0
>>> a = subprocess.call('test',shell=True)
>>> a
1
subprocess.check_call()
用法与subprocess.call()
类似,区别是,当返回值不为0时,直接抛出异常
>>> a = subprocess.check_call('df -hT',shell=True)
Filesystem Type Size Used Avail Use% Mounted on
udev devtmpfs 424M 0 424M 0% /dev
tmpfs tmpfs 87M 2.2M 85M 3% /run
/dev/vda1 ext3 50G 7.5G 40G 17% /
>>> a
0
>>> a = subprocess.check_call('test',shell=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/.pyenv/versions/3.6.6/lib/python3.6/subprocess.py", line 291, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'test' returned non-zero exit status 1.
subprocess.check_output()
用法与上面两个方法类似,区别是,如果当返回值为0时,直接返回输出结果,如果返回值不为0,直接抛出异常。该方法在python3.x中才有。
>>> a = subprocess.check_output('test',shell=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/.pyenv/versions/3.6.6/lib/python3.6/subprocess.py", line 336, in check_output
**kwargs).stdout
File "/root/.pyenv/versions/3.6.6/lib/python3.6/subprocess.py", line 418, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'test' returned non-zero exit status 1.
>>> a = subprocess.check_output('pwd',shell=True)
>>> a
b'/root\n'
subprocess.Popen()
- 将一个进程的执行输出作为另一个进程的输入
- 先进入到某个输入环境,然后再执行一系列的指令
有以下参数:
-
args
:shell命令,可以是字符串,或者序列类型,如list
,tuple
。 -
bufsize
:缓冲区大小,可不用关心 -
stdin,stdout,stderr
:分别表示程序的标准输入,标准输出及标准错误 -
shell
:与上面方法中用法相同 -
cwd
:用于设置子进程的当前目录 -
env
:用于指定子进程的环境变量。如果env=None
,则默认从父进程继承环境变量 -
universal_newlines
:不同系统的的换行符不同,当该参数设定为true
时,则表示使用\n
作为换行符
在/root
下创建一个test的目录,然后删除该目录:
>>> a = subprocess.Popen('ls',shell=True,cwd='/root')
>>> coolq-data django-web DockerCoolQ.sh software-download
>>> a
<subprocess.Popen object at 0x7f0741afba58>
>>> subprocess.Popen('mkdir test', shell=True, cwd='/root')
<subprocess.Popen object at 0x7f0741afbb00>
>>> subprocess.Popen('ls',shell=True, cwd='/root')
<subprocess.Popen object at 0x7f0741afb9e8>
>>> coolq-data django-web DockerCoolQ.sh software-download test
>>> subprocess.Popen('rm -rf test', shell=True, cwd='/root')
<subprocess.Popen object at 0x7f0741afb940>
>>> subprocess.Popen('ls',shell=True, cwd='/root')
<subprocess.Popen object at 0x7f0741afb9e8>
>>> coolq-data django-web DockerCoolQ.sh software-download
将一个子进程的输出,作为另一个子进程的输入:
import subprocess
child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
out = child2.communicate()
执行shell脚本,获取脚本中输出的内容
try:
sub = subprocess.Popen("/root/django-web/AutoUwsgi.sh", shell=True, stdout=subprocess.PIPE, cwd="/root/django-web/")
text = sub.stdout.read().decode('utf8')
print(text)
except NotADirectoryError as e:
print(e)
网友评论