python调用shell命令

python调用shell
shell对于文本有比较好的处理功能,python可以直接调用结果,但是处理的速度比较慢
一、os模块
1)os.system 方法
    原理:system函数可以将字符串转化成命令在服务器上运行;其原理是每一条system函数执行时,其会创建一个子进程在系统上执行命令行,子进程的执行结果无法影响主进程;但是几条命令同时执行的时候可能获取不到理想的结果
    使用方法:

1、直接输入命令执行
>>> import os
>>> os.system('pwd')
/root
0
>>> os.system('pwd && ls')
/root
123                              a.txt                                    fsimage1.xml        ssh.sh         user_id.sh
1.txt                            bash-4.1.2-29.el6.x86_64.rpm             install.log    


2、传参执行
os.system("shell command argusFormat" % argus)传参
>>> a='abc'
>>> os.system('python a.py %s' %(a))
haha abc
0  #返回的执行状态值 
    

返回值:os.system('command')的返回结果是脚本的退出状态码只有(0 成功),1,2

注意:os.system中不能使用管道符!!使用管道符号每次都不能执行成功

>>> os.system('echo 'abc' | passwd --stdin test')
  File "<stdin>", line 1
    os.system('echo 'abc' | passwd --stdin test')
                       ^
SyntaxError: invalid syntax

2)os.popen()方法
    原理:popen方法可以得到shell命令的返回值。os.popen(cmd)调用方式是通过管道的方式来实现,函数返回一个file-like的对象,里面的内容是脚本输出的内容(可简单理解为echo输出的内容)

    使用方法:os.popen('command')

使用管道符号
>>> os.popen('echo "abc128!" |passwd --stdin test01 ').read()
'Changing password for user test01.\npasswd: all authentication tokens updated successfully.\n'

>>> os.popen('cat /root/user_id|grep 10.17.4  |wc -l').read()
'126\n'
传参数
>>> os.popen('python a.py %s'%(a)).readlines()
['haha abc\n']

os.popen(cmd)返回值是执行结果输出内容,要再调用read()或者readlines()这两个命令

os.popen()如果命令中有' ',就需要使用双引号将其包围起来

>>> getinfo=os.popen('cat %s |grep 'auth required pam_wheel.so use_uid root_only group=wheel''%path).read().strip('\n')
  File "<stdin>", line 1
    getinfo=os.popen('cat %s |grep 'auth required pam_wheel.so use_uid root_only group=wheel''%path).read().strip('\n')
                                       ^
SyntaxError: invalid syntax
>>> getinfo=os.popen("cat %s |grep 'auth required pam_wheel.so use_uid root_only group=wheel'"%path).read().strip('\n') 
>>> print(getinfo)

Python中的commands模块专门用于调用Linux shell命令,并返回状态和结果,下面是commands模块的主要函数:
1. commands.getoutput('shell command')执行shell命令,返回结果(string类型)

1. commands.getoutput('shell command')执行shell命令,返回结果(string类型)
>>> commands.getoutput('cat /root/test1137/d.txt |grep John |wc -l')
'2'

脚本---统计文本中某匹配项出现次数
#!/use/bin/env python
import os
import sys
import commands
argvstr=sys.argv

def check(path,a,b):
    txt=commands.getoutput('cat %s |grep %s |wc -l'%(path,a))
    if eval(txt)==eval(argvstr[1]):
        print("%s"%b)


path='/root/test1137/d.txt'
a='John'
b='success'
check(path,a,b)
结果:
[root@master01 ~]# python a.py 2
success

三、subprocess模块
使用subprocess模块能够创建新的进程。能够与新建进程的输入/输出/错误管道连通。并能够获得新建进程运行的返回状态。
使用subprocess模块的目的是替代os.system()、os.popen*()、commands.*等旧的函数或模块。

1、subprocess.call(["some_command","some_argument","another_argument_or_path"])
subprocess.call(command,shell=True)
使用方法:

>>> subprocess.call('ls -l',shell=True)
total 718144
-rw-r-----   1 root root        16 Oct 22 20:22 123
-rw-r--r--   1 root root         0 Sep 29 20:30 1.txt
-rw-r--r--   1 root root       183 Sep 27 19:03 a
-rw-r--r--   1 root root       146 Oct 15 17:32 a1.sh
-rw-r--r--   1 root root       146 Oct 15 18:46 a2.sh

subprocess.call(command)commands不能使用别名,ls -l 可以,但是ll不行
>>> abc=subprocess.call('ls -l',shell=True)##和shell中命令ls -a显示结果一样
>>> print(abc)
0#返回退出的信息

返回值:父进程等待子进程完成,返回退出信息(returncode,相当于Linux exit code)

2、subprocess.Popen(command,shell=True)
假设command不是一个可运行文件。shell=True不可省。
使用subprocess模块能够创建新的进程,能够与新建进程的输入/输出/错误管道连通。并能够获得新建进程运行的返回状态。使用subprocess模块的目的是替代os.system()、os.popen*()、commands.*等旧的函数或模块。
最简单的方法是使用classsubprocess.Popen(command,shell=True)。Popen类Popen.stdin,Popen.stdout,Popen.stderr三个实用的属性,能够实现与子进程的通信。
subprocess.Popen()

>>> import subprocess
>>> child = subprocess.Popen(['ping','-c','4','blog.linuxeye.com'])
>>> print 'parent process'

实际上,上面的几个函数都是基于Popen()的封装(wrapper)。这些封装的目的在于让我们容易使用子进程。当我们想要更个性化我们的需求的时候,就要转向Popen类,该类生成的对象用来代表子进程。
与上面的封装不同,Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block),举例:
 


import subprocess
child = subprocess.Popen('ping -c4 blog.linuxeye.com',shell=True)
child.wait()
print 'parent process'

从运行结果中看到,父进程在开启子进程之后并等待child的完成后,再运行print。
此外,你还可以在父进程中对子进程进行其它操作,比如我们上面例子中的child对象:代码如下:


child.poll() # 检查子进程状态
child.kill() # 终止子进程
child.send_signal() # 向子进程发送信号
child.terminate() # 终止子进程

子进程的PID存储在child.pid
二、子进程的文本流控制
子进程的标准输入、标准输出和标准错误如下属性分别表示:

代码如下:

child.stdin
child.stdout
child.stderr

可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe),如下2个例子:


import subprocess
child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
print child1.stdout.read(),
#或者child1.communicate()
import subprocess
child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
out = child2.communicate()

subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
注意:communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成

subprocess.run():python3.5中新增的函数, 执行指定的命令, 等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。

参考链接:https://www.cnblogs.com/pengpp/p/9833349.html

  https://www.cnblogs.com/lincappu/p/8270709.html

https://www.cnblogs.com/jiangnanyanyuchen/p/8668921.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值