举例讲解Linux系统下Python调用系统Shell的方法


Posted in Python onNovember 07, 2015

时候难免需要直接调用Shell命令来完成一些比较简单的操作,比如mount一个文件系统之类的。那么我们使用Python如何调用Linux的Shell命令?下面来介绍几种常用的方法:
1. os 模块

1.1. os模块的exec方法族
Python的exec系统方法同Unix的exec系统调用是一致的。这些方法适用于在子进程中调用外部程序的情况,因为外部程序会替换当前进程的代码,不会返回。( 这个看了点 help(os)  --> search "exec" 的相关介绍,但是没太搞明白咋使用)

1.2. os模块的system方法
system方法会创建子进程运行外部程序,方法只返回外部程序的运行结果。这个方法比较适用于外部程序没有输出结果的情况。

>>> import os 
>>> os.system("echo \"Hello World\"")  # 直接使用os.system调用一个echo命令 
Hello World     ——————> 打印命令结果 
0          ——————> What's this ? 返回值? 
>>> val = os.system("ls -al | grep \"log\" ")  # 使用val接收返回值 
-rw-r--r-- 1 root    root    6030829 Dec 31 15:14 log  ——————> 此时只打印了命令结果 
>>> print val       
0          ——————> 注意,此时命令正常运行时,返回值是0 
>>> val = os.system("ls -al | grep \"log1\" ") 
>>> print val     
256         ——————> 使用os.system调用一个没有返回结果的命令,返回值为256~ 
>>>

注意:上面说了,此方法脂肪会外部程序的结果,也就是os.system的结果,所以如果你想接收命令的返回值,接着向下看~

1.3. os模块的popen方法
当需要得到外部程序的输出结果时,本方法非常有用,返回一个类文件对象,调用该对象的read()或readlines()方法可以读取输出内容。比如使用urllib调用Web API时,需要对得到的数据进行处理。os.popen(cmd) 要得到命令的输出内容,只需再调用下read()或readlines()等 如a=os.popen(cmd).read()

>>> os.popen('ls -lt')         # 调用os.popen(cmd)并不能得到我们想要的结果 
<open file 'ls -lt ', mode 'r' at 0xb7585ee8> 
>>> print os.popen('ls -lt').read()   # 调用read()方法可以得到命令的结果 
total 6064 
-rwxr-xr-x 1 long    long      23 Jan 5 21:00 hello.sh 
-rw-r--r-- 1 long    long      147 Jan 5 20:26 Makefile 
drwxr-xr-x 3 long    long     4096 Jan 2 19:37 test 
-rw-r--r-- 1 root    root    6030829 Dec 31 15:14 log 
drwxr-xr-x 2 long    long     4096 Dec 28 09:36 pip_build_long 
drwx------ 2 Debian-gdm Debian-gdm  4096 Dec 23 19:08 pulse-gylJ5EL24GU9 
drwx------ 2 long    long     4096 Jan 1 1970 orbit-long 
>>> val = os.popen('ls -lt').read()   # 使用变量可以接收命令返回值 
>>> if "log" in val:          # 我们可以使用in来判断返回值中有木有一个字符串 
...   print "Haha,there is the log" 
... else: 
...   print "No,not happy" 
... 
Haha,there is the log

2. commands 模块

使用commands模块的getoutput方法,这种方法同popend的区别在于popen返回的是一个类文件对象,而本方法将外部程序的输出结果当作字符串返回,很多情况下用起来要更方便些。
主要方法: 
*   commands.getstatusoutput(cmd)         返回(status, output)
*   commands.getoutput(cmd)                   只返回输出结果
*   commands.getstatus(file)                     返回ls -ld file的执行结果字符串,调用了getoutput,不建议使用此方法

long@zhouyl:/tmp/tests$ python 
Python 2.7.3 (default, Jan 2 2013, 16:53:07)  
[GCC 4.7.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import commands 
>>> commands.getstatusoutput('ls -lt')   # 返回(status, output) 
(0, 'total 5900\n-rwxr-xr-x 1 long long   23 Jan 5 21:34 hello.sh\n-rw-r--r-- 1 long long   147 Jan 5 21:34 Makefile\n-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log') 
>>> commands.getoutput('ls -lt')      # 返回命令的输出结果(貌似和Shell命令的输出格式不同哈~) 
'total 5900\n-rwxr-xr-x 1 long long   23 Jan 5 21:34 hello.sh\n-rw-r--r-- 1 long long   147 Jan 5 21:34 Makefile\n-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log' 
>>> commands.getstatus('log')        # 调用commands.getoutput中的命令对'log'文件进行相同的操作 
'-rw-r--r-- 1 long long 6030829 Jan 5 21:34 log' 
>>>

3. subprocess模块

根据Python官方文档说明,subprocess模块用于取代上面这些模块。有一个用Python实现的并行ssh工具—mssh,代码很简短,不过很有意思,它在线程中调用subprocess启动子进程来干活。
>>> from subprocess import call 
>>> call(["ls", "-l"]) 

subprocess与system相比的优势是它更灵活(你可以得到标准输出,标准错误,“真正”的状态代码,更好的错误处理,等..)。我认为使用os.system已过时,或即将过时。

4. 众方法的比较以及总结
4.1. 关于 os.system
os.system("some_command with args")将命令以及参数传递给你的系统shell,这很好,因为你可以用这种方法同时运行多个命令并且可以设置管道以及输入输出重定向。比如:
os.system("some_command < input_file | another_command > output_file")
然而,虽然这很方便,但是你需要手动处理shell字符的转义,比如空格等。此外,这也只能让你运行简单的shell命令而且不能运行外部程序。

4.2. 关于os.popen
使用stream = os.popen("some_command with args")也能做与os.system一样的事,与os.system不同的是os.popen会返回一个类文件对象,使用它来访问标准输入、输出。
4.3. 关于subprocess.popen
subprocess模块的Popen类,意图作为os.popen的替代,但是因为其很全面所以比os.popen要显得稍微复杂。
比如你可以使用  print Popen("echo Hello World", stdout=PIPE, shell=True).stdout.read()  来替代  print os.popen("echo Hello World").read()。但是相比之下它使用一个统一的类包括4中不同的popen函数还是不错的。

4.4. 关于subprocess.call
subprocess模块的call函数。它基本上就像Popen类并都使用相同的参数,但是它只简单的等待命令完成并给你返回代码。比如:

return_code = subprocess.call("echo Hello World", shell=True)

os模块中还有C中那样的fork/exec/spawn函数,但是我不建议直接使用它们。subprocess可能更加适合你。

python和shell读取文件某一行

python和shell(awk命令) 可以实现直接读取文件的某一行,按行号进行读取 。并可以精准的取得该行的某个字段,这个有点类似于x轴、y轴定位某个点的操作。

一、awk取某行某列值

awk 可以设置条件来输出文件中m行到n行中每行的指定的k字段,使用格式如下:

awk  'NR==m,NR==n {print $k}' path/filename

m,n,k表示实在的数值。如果要用变量来表示m,n的值,则变量需要用单引号将其引起来。NR,{print }是awk命令在此用法下的规定字段;path/filename表示读取文件的路径及文件名。这里指定了两行,如果只指定一行,可以这样写:

awk  'NR==m {print $k}' path/filename

二、python取某行某列

标准库提供的linecache模块提供具体取某一行的方法:

import linecache
theline = linecache.getline(filepath, line_number)

取到相关的行以后,再对theline做split切分成list,再对list索引取值就行了。如theline.split()[2] 。

三、linecache模块的用法

即然,提到了linecache模块,这里就列下linecache的其他方法。linecache模块允许从任何文件里得到任何的行,并且使用缓存进行优化,常见的情况是从单个文件读取多行。

linecache.getlines(filename) 从名为filename的文件中得到全部内容,输出为列表格式,以文件每行为列表中的一个元素,并以linenum-1为元素在列表中的位置存储
linecache.getline(filename,lineno) 从名为filename的文件中得到第lineno行。这个函数从不会抛出一个异常?产生错误时它将返回”(换行符将包含在找到的行里)。如果文件没有找到,这个函数将会在sys.path搜索。
linecache.clearcache() 清除缓存。如果你不再需要先前从getline()中得到的行
linecache.checkcache(filename) 检查缓存的有效性。如果在缓存中的文件在硬盘上发生了变化,并且你需要更新版本,使用这个函数。如果省略filename,将检查缓存里的所有条目。
linecache.updatecache(filename) 更新文件名为filename的缓存。如果filename文件更新了,使用这个函数可以更新linecache.getlines(filename)返回的列表。
示例:

# cat a.txt
1a
2b
3c
4d
5e
6f
7g

1、获取a.txt文件的内容

>>> a=linecache.getlines('a.txt')
>>> a
['1a\n', '2b\n', '3c\n', '4d\n', '5e\n', '6f\n', '7g\n']

2、获取a.txt文件中第1-4行的内容

>>> a=linecache.getlines('a.txt')[0:4]
>>> a
['1a\n', '2b\n', '3c\n', '4d\n']

3、获取a.txt文件中第4行的内容

>>> a=linecache.getline('a.txt',4)
>>> a
'4d\n'

注意:

使用linecache.getlines('a.txt')打开文件的内容之后,如果a.txt文件发生了改变,如你再次用linecache.getlines获取的内容,不是文件的最新内容,还是之前的内容,此时有两种方法:

1、使用linecache.checkcache(filename)来更新文件在硬盘上的缓存,然后在执行linecache.getlines('a.txt')就可以获取到a.txt的最新内容;

2、直接使用linecache.updatecache('a.txt'),即可获取最新的a.txt的最新内容。

读取文件之后你不需要使用文件的缓存时需要在最后清理一下缓存,使linecache.clearcache()清理缓存,释放缓存。

Python 相关文章推荐
Python编写的com组件发生R6034错误的原因与解决办法
Apr 01 Python
Python开发常用的一些开源Package分享
Feb 14 Python
Python实现将n个点均匀地分布在球面上的方法
Mar 12 Python
简单介绍Python中的几种数据类型
Jan 02 Python
运动检测ViBe算法python实现代码
Jan 09 Python
详解用python自制微信机器人,定时发送天气预报
Mar 25 Python
Django实现文件上传下载
Oct 06 Python
django数据模型on_delete, db_constraint的使用详解
Dec 24 Python
python标准库os库的函数介绍
Feb 12 Python
django中url映射规则和服务端响应顺序的实现
Apr 02 Python
Python实现CAN报文转换工具教程
May 05 Python
python各种excel写入方式的速度对比
Nov 10 Python
使用Python导出Excel图表以及导出为图片的方法
Nov 07 #Python
Windows下为Python安装Matplotlib模块
Nov 06 #Python
python 的列表遍历删除实现代码
Apr 12 #Python
举例讲解Python中的死锁、可重入锁和互斥锁
Nov 05 #Python
用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动
Nov 05 #Python
python实现将内容分行输出
Nov 05 #Python
Python IDE PyCharm的基本快捷键和配置简介
Nov 04 #Python
You might like
乐信RP2100的电路分析和打磨
2021/03/02 无线电
以文本方式上传二进制文件的PHP程序
2006/10/09 PHP
PHP字符串比较函数strcmp()和strcasecmp()使用总结
2014/11/19 PHP
Jquery Ajax学习实例5 向WebService发出请求,返回泛型集合数据的异步调用
2010/03/17 Javascript
理解Javascript_07_理解instanceof实现原理
2010/10/15 Javascript
javascript整除实现代码
2010/11/23 Javascript
Asp.Net alert弹出提示信息的几种方法总结
2014/01/29 Javascript
js实现图片旋转的三种方法
2014/04/10 Javascript
JavaScript 控制字体大小设置的方法
2016/11/23 Javascript
jQuery实现圣诞节礼物动画案例解析
2016/12/25 Javascript
深入理解AngularJs-scope的脏检查(一)
2017/06/19 Javascript
使用webpack打包koa2 框架app
2018/02/02 Javascript
vue实现树形菜单效果
2018/03/19 Javascript
ES6知识点整理之数组解构和字符串解构的应用示例
2019/04/17 Javascript
了解javascript中变量及函数的提升
2019/05/27 Javascript
深入了解JavaScript代码覆盖
2019/06/13 Javascript
mock.js模拟前后台交互
2019/07/25 Javascript
微信小程序 行的删除和增加操作实现详解
2019/09/29 Javascript
基于Echarts图表在div动态切换时不显示的解决方式
2020/07/20 Javascript
Vue中引入svg图标的两种方式
2021/01/14 Vue.js
Python中urllib2模块的8个使用细节分享
2015/01/01 Python
python 网络爬虫初级实现代码
2016/02/27 Python
python版opencv摄像头人脸实时检测方法
2018/08/03 Python
django之静态文件 django 2.0 在网页中显示图片的例子
2019/07/28 Python
Django分页功能的实现代码详解
2019/07/29 Python
python判断变量是否为int、字符串、列表、元组、字典的方法详解
2020/02/13 Python
html5利用canvas实现颜色容差抠图功能
2019/12/23 HTML / CSS
html5 横向滑动导航栏的方法示例
2020/05/08 HTML / CSS
SQL里面如何插入自动增长序列号字段
2012/03/29 面试题
什么是Remote Module
2016/06/10 面试题
爽歪歪广告词
2014/03/20 职场文书
家长对学生的评语
2014/04/18 职场文书
设计专业自荐信
2014/06/19 职场文书
企业员工集体活动方案
2014/08/17 职场文书
中秋节作文(五年级)之关于月亮
2019/09/11 职场文书
OpenCV3.3+Python3.6实现图片高斯模糊
2021/05/18 Python