举例讲解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 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)返回的列表。
示例:

?


1

# cat a.txt

?


1

2

3

4

5

6

7

1a

2b

3c

4d

5e

6f

7g

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

时间: 2024-10-15 18:43:09

举例讲解Linux系统下Python调用系统Shell的方法的相关文章

linux系统下重启tomcat的shell脚本

linux系统下重启tomcat的shell脚本: tomcat_home=/opt/apache-tomcat-6.0.32 #找到tomcat进程的id并kill掉 ps -ef |grep tomcat |awk {'print $2'} | sed -e "s/^/kill -9 /g" | sh - #删除日志文件,如果你不先删除可以不要下面一行 rm $tomcat_home/logs/* -rf #删除tomcat的临时目录 rm $tomcat_home/work/*

Windows系统下Python与NumPy安装方法

Windows系统下Python与NumPy安装方法 Windows下Python的某些第三方包安装步骤实在是太麻烦了(这里主要以NumPy为例,目前只有遇到安装它的时候出现了很多问题),晚上花了好几个小时才把NumPy科学计算包安装好,在这里描述下安装过程,避免大家走没有必要的弯路. 1,安装Python 首先,运行下载的MSI安装包,选择安装组件时,确保勾上了所有的组件. 特别要注意选上pip和Add python.exe to Path,然后多次点击Next即可完成安装. Python解释

Windows 7系统下删除开机引导项的方法

Windows 7系统下删除开机引导项的方法: 1.使用管理员权限运行cmd,在命令行窗口使用  bcdedit 回车 2.查找description为你想删除的段,看对应的标识符是多少, 然后使用 bcdedit  /f  /delete 标识符 示例: bcdedit  /f  /delete {fa817679-23c9-11e1-bcbd-a9093a3d5fb5} 3. win7系统有一个启动管理器 bootmgr 它有一个状态displaybootmenu 默认是no 如果做过多系统

linux平台上面python调用c

不能免俗,先打印个helloworld出来,c代码的函数 hello.c #include <stdio.h> int helloworld() { printf("hello world!"); return 0; } 然后编译成动态链接库 gcc hello.c -fPIC -shared -o libhello.so 最后在python中引入ctypes这个包,然后通过一个对dlopen包装的CDLL就可以引用so中的代码 import ctypes so=ctype

Win2008 r2 iis7/iis7.5系统下HTTP重定向(301重定向)图文方法

这篇文章主要介绍了Win2008 r2 iis7/iis7.5系统下HTTP重定向(301重定向)图文方法,需要的朋友可以参考下首先了解一下重定向,常用的重定向方式有: 301 redirect, 302 redirect 与 meta fresh.什么情况下需要做301重定向?如果你想要换域名,可以通过做301重定向来实现搜索引擎上你的网页依然有效和PR及其他数据不变等对搜索引擎友好的效果,保证流量稳定.如果你有多个主页网址,也就是说访问者可以通过不同的URL到达相同的网页的时候,这种情况也就

解决linux系统下python中的matplotlib模块内的pyplot输出图片不能显示中文的问题

问题: 我在ubuntu14.04下用python中的matplotlib模块内的pyplot输出图片不能显示中文,怎么解决呢? 解决: 1.指定默认编码为UTF-8: 在python代码开头加入如下代码 import sys reload(sys) sys.setdefaultencoding('utf-8') 2.确认你ubuntu系统环境下拥有的中文字体文件: 在终端运行命令"fc-list :lang=zh",得到自己系统的中文字体 命令输出如下: /usr/share/fon

Android 实例讲解添加本地图片和调用系统拍照图片

在项目的开发过程我们离不开图片,而有时候需要调用本地的图片,有时候需要调用拍照图片.同时实现拍照的方法有两种,一种是调用系统拍照功能,另一种是自定义拍照功能.而本博文目前只讲解第一种方法,第二种方法后期在加以讲解. 添加本地图片和调用系统拍照图片主要是通过调用acitivity跳转startActivityForResult(Intent intent, int requestCode)方法和activity返回结果onActivityResult(int requestCode, int re

Windows系统下 Python(Anaconda)的 Dlib 库 的安装

0. 引言 介绍 Windows 10 64位 系统下,利用 Anaconda 开发环境,在 Python 中安装 Dlib库 : windows 下 dlib 的安装十分不友好,所以在这里分享下安装过程: Windows10 + Anaconda + pip + Dlib : (借助 Anaconda 的话,不需要自己 build 和 make 源码, cmake 和 boost 这里不需要,操作友好很多) 1. Dlib的简介(官网:http://dlib.net/) Dlib 是一个机器学

linux下python调用c模块

在C调用Python模块时需要初始化Python解释器,导入模块等,但Python调用C模块却比较简单,下面还是以helloWorld.c 和 main.py 做一说明:   (1)编写C代码,hello.c代码很简单,只是输出“Hello World!”:         (2)将编写的C代码编译成动态链接库的形式,具体命令:   此时在当前目录下就生成了libhello.so 的动态链接库:         (3)在main.py中导入动态链接库,并调用C函数 这里的ctypes是Pytho