举例讲解Linux系统下Python调用系统Shell的方法
有时候难免需要直接调用Shell命令来完成一些比较简单的操作,比如mount一个文件系统之类的。那么我们使用Python如何调用Linux的Shell命令?下面来介绍几种常用的方法:
1. os 模块
1.1. os模块的exec方法族
Python的exec系统方法同Unix的exec系统调用是一致的。这些方法适用于在子进程中调用外部程序的情况,因为外部程序会替换当前进程的代码,不会返回。( 这个看了点 help(os) --> search "exec" 的相关介绍,但是没太搞明白咋使用)
1.2. os模块的system方法
system方法会创建子进程运行外部程序,方法只返回外部程序的运行结果。这个方法比较适用于外部程序没有输出结果的情况。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> 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()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
>>> 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,不建议使用此方法
|
1
2
3
4
5
6
7
8
9
10
11
12
|
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类并都使用相同的参数,但是它只简单的等待命令完成并给你返回代码。比如:
|
1
|
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字段,使用格式如下:
|
1
|
awk 'NR==m,NR==n {print $k}' path/filename |
m,n,k表示实在的数值。如果要用变量来表示m,n的值,则变量需要用单引号将其引起来。NR,{print }是awk命令在此用法下的规定字段;path/filename表示读取文件的路径及文件名。这里指定了两行,如果只指定一行,可以这样写:
|
1
|
awk 'NR==m {print $k}' path/filename |
二、python取某行某列
标准库提供的linecache模块提供具体取某一行的方法:
|
1
2
|
import linecachetheline = 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)返回的列表。
示例:
|
1
|
# cat a.txt |
|
1
2
3
4
5
6
7
|
1a2b3c4d5e6f7g |
1、获取a.txt文件的内容
|
1
2
3
|
>>> 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行的内容
|
1
2
3
|
>>> a=linecache.getlines('a.txt')[0:4]>>> a['1a\n', '2b\n', '3c\n', '4d\n'] |
3、获取a.txt文件中第4行的内容
|
1
2
3
|
>>> 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()清理缓存,释放缓存。
借鉴的网址:http://www.jb51.net/article/74508.htm
举例讲解Linux系统下Python调用系统Shell的方法的更多相关文章
- Linux系统下python代码运行shell命令的方法
方法一:os.popen #!/usr/bin/python # -*- coding: UTF-8 -*- import os, sys # 使用 mkdir 命令 a = 'ls' b = os. ...
- ubuntu系统下Python虚拟环境的安装和使用
ubuntu系统下Python虚拟环境的安装和使用 前言:进行python项目开发的时候,由于不同的项目需要使用不同的资源包和相关的配置,因此创建多个python虚拟环境,在虚拟环境下开 ...
- linux系统下重启tomcat的shell脚本
linux系统下重启tomcat的shell脚本: #!/bin/shtomcat_home=/opt/apache-tomcat- #找到tomcat进程的id并kill掉 ps -ef |grep ...
- Linux环境下Python的安装过程
Linux环境下Python的安装过程 前言 一般情况下,Linux都会预装 Python了,但是这个预装的Python版本一般都非常低,很多 Python的新特性都没有,必须重新安装新一点的版本,从 ...
- Windows 7系统下删除开机引导项的方法
Windows 7系统下删除开机引导项的方法: 1.使用管理员权限运行cmd,在命令行窗口使用 bcdedit 回车 2.查找description为你想删除的段,看对应的标识符是多少, 然后使用 ...
- linux下java调用.so文件的方法1: JNI
摘自http://blog.163.com/squall_smile/blog/static/6034984020129296931793/ https://my.oschina.net/simabe ...
- linux环境下 python环境import找不到自定义的模块
linux环境下 python环境import找不到自定义的模块 问题现象: Linux环境中自定义的模块swport,import swport 出错.swport模块在/root/sw/目录下. ...
- windows系统下ruby开发环境的搭建方法
ruby是一种简单快捷的面向对象的脚本语言,非常直观.下面说一下windows系统下ruby开发环境的搭建方法. 工具/原料 rubyinstaller.exe 方法/步骤 1 到如下网站去下载最新的 ...
- Linux CentOS下Python+robot framework环境搭建
Linux CentOS下Python+robot framework环境搭建 by:授客 QQ:1033553122 操作系统环境:CentOS 6.5-x86_64 下载地址:http://w ...
随机推荐
- Java识别操作系统
/** * Created by xfyou on 2016/11/3. */ public class SysDep { final static String UNIX_NULL_DEV = &q ...
- 网上图书商城1--User模块
1. 注册 $(function() { /* * 1. 得到所有的错误信息,循环遍历之.调用一个方法来确定是否显示错误信息! */ $(".errorClass").each(f ...
- JavaScript学习(1):基础
这篇文章里,我们来聊一些JavaScript的基础知识. 1. 如何运行JavaScript? JavaScript是一种解释型的语言,它不需要提前编译.通常情况下,JavaScript会放在网页中, ...
- Frameless - 用于预览 iOS8 原型的浏览器
Frameless 是一个用于在 iOS8 中预览产品原型的浏览器.可以可以帮助那些需要一个简单的方法来预览 iOS 设备上的原型设计和开发效果.没有状态栏,通过手势控制浏览器的历史以及键盘的显示. ...
- 前端优秀作品展示,JavaScript 版水果忍者
<水果忍者>是一款非常受喜欢的手机游戏,刚看到新闻说<水果忍者>四周年新版要上线了.网页版的切水果游戏由百度 JS 小组开发,采用 vml + svg 绘图,使用了 Rapha ...
- CSS之详解:active选择器
Active的一段话 active的英文解释为"积极的",表现在鼠标上就是点击的意思.关于active选择器最多的示例恐怕就是应用在链接上面的,然而打开链接是一个一瞬间的动作,这不 ...
- React入门--------组件的生命周期
Mounting/组件挂载相关: componentWillMount componentDidMount Updating/组件更新相关: componentWillReceiveProps sho ...
- 仿iphone日历插件(beta)
前言 小伙伴们好,很久不见了.最近工作进入正常期了,所以慢慢的悠闲的时间久没有了,所以不能每天水一篇了. 最近也在听师傅(http://home.cnblogs.com/u/aaronjs/)的教导开 ...
- 【初探移动前端开发05】jQuery Mobile (整合版)
前言 为了方便大家看的方便,我这里将这几天的东西整合一下发出. 里面的例子请使用手机浏览器查看. 什么是jQuery Mobile? jquery mobile是jquery在移动设备上的版本,他是基 ...
- 强大的<canvas>
<canvas> 个人认为<canvas>是h5最重量级的新标签了,现在各种h5小游戏都是基于<canvas>的,它为游戏提供了一个功能强大的画布,可在画布上绘制丰 ...