Python下调用Linux的Shell命令的方法


Posted in Python onJune 12, 2018

有时候难免需要直接调用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方法

当需要得到外部程序的输出结果时,本方法非常有用。比如使用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返回的是一个文件句柄,而本方法将外部程序的输出结果当作字符串返回,很多情况下用起来要更方便些。
主要方法: 

  1. commands.getstatusoutput(cmd)         返回(status, output)
  2. commands.getoutput(cmd)                   只返回输出结果
  3. 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会给你一个像文件的对象从而你可以使用它来访问哪个程序的标准输入、输出。而且popen还有三个变种都是在I/O处理上有轻微不同。假如你通过一个字符串传递所有东西,你的命令会传递给shell;如果你通过一个列表传递他们,你不用担心逃避任何事。

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 相关文章推荐
关于Python元祖,列表,字典,集合的比较
Jan 06 Python
python3中str(字符串)的使用教程
Mar 23 Python
深入学习Python中的上下文管理器与else块
Aug 27 Python
详解python 拆包可迭代数据如tuple, list
Dec 29 Python
python随机在一张图像上截取任意大小图片的方法
Jan 24 Python
Python opencv实现人眼/人脸识别以及实时打码处理
Apr 29 Python
python跳出双层for循环的解决方法
Jun 24 Python
pytorch 使用单个GPU与多个GPU进行训练与测试的方法
Aug 19 Python
详解在python操作数据库中游标的使用方法
Nov 12 Python
tensorflow实现打印ckpt模型保存下的变量名称及变量值
Jan 04 Python
python如何控制进程或者线程的个数
Oct 16 Python
关于python scrapy中添加cookie踩坑记录
Nov 17 Python
Centos 升级到python3后pip 无法使用的解决方法
Jun 12 #Python
解决python升级引起的pip执行错误的问题
Jun 12 #Python
基于windows下pip安装python模块时报错总结
Jun 12 #Python
完美解决Python 2.7不能正常使用pip install的问题
Jun 12 #Python
无法使用pip命令安装python第三方库的原因及解决方法
Jun 12 #Python
pip命令无法使用的解决方法
Jun 12 #Python
解决Python安装后pip不能用的问题
Jun 12 #Python
You might like
也谈 PHP 和 MYSQL
2006/10/09 PHP
我的论坛源代码(四)
2006/10/09 PHP
删除数组元素实用的PHP数组函数
2008/08/18 PHP
PHP在字符串中查找指定字符串并删除的代码
2008/10/02 PHP
php带密码功能并下载远程文件保存本地指定目录 修改加强版
2010/05/16 PHP
PHP数字和字符串ID互转函数(类似优酷ID)
2014/06/30 PHP
PHP生成网站桌面快捷方式代码分享
2014/10/11 PHP
Javascript学习笔记8 用JSON做原型
2010/01/11 Javascript
jquery插件开发之实现md5插件
2014/03/17 Javascript
javascript学习笔记之10个原生技巧
2014/05/21 Javascript
javascript制作sql转换为stringBuffer的小工具
2015/04/03 Javascript
javascript实现鼠标移到Image上方时显示文字效果的方法
2015/08/07 Javascript
jQuery实现垂直半透明手风琴特效代码分享
2015/08/21 Javascript
JavaScript获取css行间样式,内连样式和外链样式的简单方法
2016/07/18 Javascript
利用Node.js+Koa框架实现前后端交互的方法
2017/02/27 Javascript
nodejs中解决异步嵌套循环和循环嵌套异步的问题
2017/07/12 NodeJs
详解HTML5 使用video标签实现选择摄像头功能
2017/10/25 Javascript
详解Vue组件插槽的使用以及调用组件内的方法
2018/11/13 Javascript
在vue中使用G2图表的示例代码
2019/03/19 Javascript
Python threading多线程编程实例
2014/09/18 Python
Python 使用os.remove删除文件夹时报错的解决方法
2017/01/13 Python
深入理解Python中的内置常量
2017/05/20 Python
浅谈python中对于json写入txt文件的编码问题
2018/06/07 Python
使用python批量读取word文档并整理关键信息到excel表格的实例
2018/11/07 Python
Python面向对象程序设计类的封装与继承用法示例
2019/04/12 Python
使用TensorFlow实现简单线性回归模型
2019/07/19 Python
Python生成验证码、计算具体日期是一年中的第几天实例代码详解
2019/10/16 Python
南非最大的在线时尚商店:Zando
2019/07/21 全球购物
蔬菜基地的创业计划书
2014/01/06 职场文书
情侣吵架检讨书
2014/02/05 职场文书
国旗下的讲话演讲稿
2014/05/08 职场文书
流动人口婚育证明范本
2014/09/26 职场文书
2015年社区反邪教工作总结
2015/10/14 职场文书
Java实现添加条码或二维码到Word文档
2022/06/01 Java/Android
Win11 Build 22000.829更新补丁KB5015882发布(附更新修复内容汇总)
2022/07/15 数码科技
Nginx如何限制IP访问只允许特定域名访问
2022/07/23 Servers