一、os.system方法
1、返回值
执行操作系统的命令,将结果输出到屏幕,只返回命令执行状态(0:成功,非 0 : 失败)
>>> result = os.system('pwd')
/root
>>> result
0
2、阻塞
在执行os.system函数的时候通常会阻塞它的调用者,等待所启动的命令行程序退出。
在Linux平台上 只需要在命令末尾加上shell后台运算符&即可。
二、os.popen方法
执行操作系统的命令,会将结果保存在file对象当中,可以用read()、readlines()等
方法读取出来
import
os
result
=
os.popen(
'cat /etc/passwd'
)
print
(result.read())
三、commands模块
关于 commands 的说明:
- python 3.0 之后移除此命令,使用 subprocess代替;
- python 3.x 使用 subprocess 创建一个新进程;
四、subprocess模块
Subprocess是一个功能强大的子进程管理模块,是替换
- os.system
- os.spawn*
- os.popen*
- popen2.*
- commands.*
等方法的一个模块。
当执行命令的参数或者返回中包含了中文文字,那么建议使用subprocess。
1、subprocess.run()
1.1、 python 解析则传入命令的每个参数的列表
>>> import subprocess
>>> subprocess.run(["df",'-h'])
Filesystem Size Used Avail Use% Mounted on
/dev/vda3 196G 34G 163G 17% /
devtmpfs 906M 0 906M 0% /dev
tmpfs 920M 22M 899M 3% /dev/shm
tmpfs 920M 67M 854M 8% /run
tmpfs 920M 0 920M 0% /sys/fs/cgroup
/dev/vda1 497M 154M 344M 31% /boot
tmpfs 184M 40K 184M 1% /run/user/0
CompletedProcess(args=['df', '-h'], returncode=1)
>>>
1.2、需要交给Linux shell自己解析,则:传入命令字符串,shell=True
>>> subprocess.run("df -h | grep /dev/vda3",shell=True)
/dev/vda3 196G 34G 163G 17% /
CompletedProcess(args='df -h | grep /dev/vda3', returncode=0)
>>>
2、subprocess.call()
执行命令,返回命令的结果和执行状态,0或者非0
>>> res
=
subprocess.call([
"ls"
,
"-l"
])
总用量
28
-
rw
-
r
-
-
r
-
-
1
root root
0
6
月
16
10
:
28
1
drwxr
-
xr
-
x
2
root root
4096
6
月
22
17
:
48
_1748
-
rw
-
-
-
-
-
-
-
.
1
root root
1264
4
月
28
20
:
51
anaconda
-
ks.cfg
drwxr
-
xr
-
x
2
root root
4096
5
月
25
14
:
45
monitor
-
rw
-
r
-
-
r
-
-
1
root root
13160
5
月
9
13
:
36
npm
-
debug.log
# 命令执行状态
>>> res
0
3、subprocess.check_call()
执行命令,返回结果和状态,正常为0 ,执行错误则抛出异常
3.1、正常情况
>>> subprocess.check_call([
"ls"
,
"-l"
])
总用量
28
-
rw
-
r
-
-
r
-
-
1
root root
0
6
月
16
10
:
28
1
drwxr
-
xr
-
x
2
root root
4096
6
月
22
17
:
48
_1748
-
rw
-
-
-
-
-
-
-
.
1
root root
1264
4
月
28
20
:
51
anaconda
-
ks.cfg
drwxr
-
xr
-
x
2
root root
4096
5
月
25
14
:
45
monitor
-
rw
-
r
-
-
r
-
-
1
root root
13160
5
月
9
13
:
36
npm
-
debug.log
0
3.2、错误情况
>>> result=subprocess.check_call(["lm","-l"])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/python3/lib/python3.6/subprocess.py", line 286, in check_call
retcode = call(*popenargs, **kwargs)
File "/usr/local/python3/lib/python3.6/subprocess.py", line 267, in call
with Popen(*popenargs, **kwargs) as p:
File "/usr/local/python3/lib/python3.6/subprocess.py", line 707, in __init__
restore_signals, start_new_session)
File "/usr/local/python3/lib/python3.6/subprocess.py", line 1326, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'lm'
4、subprocess.getstatusoutput()
接受字符串形式的命令,返回 一个元组形式的结果,第一个元素是命令执行状态,第二个为执行结果
4.1、执行正确
>>> result = subprocess.getstatusoutput("pwd")
>>> result
(0, '/root')
4.2、执行错误
>>> result = subprocess.getstatusoutput("pwdd")
>>> result
(127, '/bin/sh: pwdd: command not found')
5、subprocess.getoutput()
接受字符串形式的命令,返回执行结果
5.1、执行命令正常
>>> result = subprocess.getoutput("pwd")
>>> result
'/root'
5.2、执行命令出错
>>> result = subprocess.getoutput("pwdd")
>>> result
'/bin/sh: pwdd: command not found'
>>>
6、subprocess.check_output()
6.1、执行命令正常,以字节形式返回
>>> result = subprocess.check_output("pwd")
>>> result
b'/root\n' # 结果以字节形式返回
6.2、执行命令出错,抛出异常
>>> result = subprocess.check_output("pwdd")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/python3/lib/python3.6/subprocess.py", line 336, in check_output
**kwargs).stdout
File "/usr/local/python3/lib/python3.6/subprocess.py", line 403, in run
with Popen(*popenargs, **kwargs) as process:
File "/usr/local/python3/lib/python3.6/subprocess.py", line 707, in __init__
restore_signals, start_new_session)
File "/usr/local/python3/lib/python3.6/subprocess.py", line 1326, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'pwdd'
>>>
import
subprocess
res
=
subprocess.Popen(
'cat /etc/passwd'
, shell
=
True
, stdout
=
subprocess.PIPE, stderr
=
subprocess.STDOUT)
# 使用管道
# print res.stdout.read() # 标准输出
for
line
in
res.stdout.readlines():
print
line
res.stdout.close()
# 关闭
7、subprocess.Popen()
其实前面subprocess使用的方法,都是对subprocess.Popen的封装,下面我们就来看看这个Popen方法。
7.1、stdout
标准输出
>>> res
=
subprocess.Popen(
"ls /tmp/yum.log"
, shell
=
True
, stdout
=
subprocess.PIPE)
# 使用管道
>>> res.stdout.read()
# 标准输出
b
'/tmp/yum.log\n'
res.stdout.close()
# 关闭
7.2、stderr
标准错误
>>>
import
subprocess
>>> res
=
subprocess.Popen(
"lm -l"
,shell
=
True
,stdout
=
subprocess.PIPE,stderr
=
subprocess.PIPE)
# 标准输出为空
>>> res.stdout.read()
b''
#标准错误中有错误信息
>>> res.stderr.read()
b
'/bin/sh: lm: command not found\n'
注意:上面的提到的标准输出都为啥都需要等于subprocess.PIPE,这个又是啥呢?原来这个是一个管道,这个需要画一个图来解释一下
7.3、poll()
定时检查命令有没有执行完毕,执行完毕后返回执行结果的状态,没有执行完毕返回None
>>> res = subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> print(res.poll())
None
>>> print(res.poll())
None
>>> print(res.poll())
0
7.4、wait()
等待命令执行完成,并且返回结果状态
>>> obj
=
subprocess.Popen(
"sleep 10;echo 'hello'"
,shell
=
True
,stdout
=
subprocess.PIPE,stderr
=
subprocess.PIPE)
>>> obj.wait()
# 中间会一直等待
0
7.5、terminate()
结束进程
import
subprocess
>>> res
=
subprocess.Popen(
"sleep 20;echo 'hello'"
,shell
=
True
,stdout
=
subprocess.PIPE,stderr
=
subprocess.PIPE)
>>> res.terminate()
# 结束进程
>>> res.stdout.read()
b''
7.6、pid
获取当前执行子shell的程序的进程号
import
subprocess
>>> res
=
subprocess.Popen(
"sleep 5;echo 'hello'"
,shell
=
True
,stdout
=
subprocess.PIPE,stderr
=
subprocess.PIPE)
>>> res.pid
# 获取这个linux shell 的 进程号
2778