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 syntax2)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