python模块:调用系统命令模块subprocess等

来源:转载

http://blog.csdn.net/pipisorry/article/details/46972171


Python经常被称作“胶水语言”,因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库。在Python/wxPython环境下,执行外部命令或者说在Python程序中启动另一个程序的方法。


1、os.system(command)

os.system()函数用来运行shell命令。此命令可以方便的调用或执行其他脚本和命令


#打开指定的文件 >>>os.system('notepad *.txt')

这个调用相当直接,且是同步进行的,程序需要阻塞并等待返回。返回值是依赖于系统的,直接返回系统的调用返回值,所以windows和linux是不一样的。


2、wx.Execute(command, syn=wx.EXEC_ASYNC, callback=None)

若置syn为wx.EXEC_ASYNC则wx.Excute函数立即返回,若syn=wx.EXEC_SYNC则等待调用的程序结束后再返回。


callback是一个wx.Process变量,如果callback不为None且syn=wx.EXEC_ASYNC,则程序结束后将调用wx.Process.OnTerminate()函数。


os.system()和wx.Execute()都利用系统的shell,执行时会出现shell窗口。如在Windows下会弹出控制台窗口,不美观。下面的两种方法则没有这个缺点。


3、import subprocess

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)


subprocess.call(["cmd","arg1","arg2"],shell=True)

Note:


1. 参数args可以是字符串或者序列类型(如:list,元组),用于指定进程的可执行文件及其参数。


2. 如果command(args)不是一个可执行文件,shell=True不可省。否则如copy/del命令可能会出现FileNotFoundError错误。


3. Popen.wait()可以得到命令的返回值


4.如果是windows下的命令,则文件路径如果用的是linux格式会报错:The syntax of the command is incorrect.


举个栗子

if subprocess.Popen('dir /b %s' % filename, shell=True).wait() == 0如果filename字符串中有空格,则会出现错误:File Not Found错误

可以通过下面["cmd","arg1","arg2"]两种方式

if subprocess.Popen(["dir", "/b", filename], shell=True).wait() == 0
if subprocess.call(["dir", "/b", filename], shell=True) == 0

[Python中subprocess学习]


4、webbrowser.open(url)

前面三个方法只能用于执行程序和打开文件,不能处理URL,打开URL地址可用webbrowser模块提供的功能。


调用系统缺省浏览器打开URL地址,如 webbrowser.open('http://www.jb51.net'),也可以利用webbrowser.open('h:/python.zip')来执行程序。这样可以不必区分是文件名还是URL,不知道在Linux下是否可行。以上在Windows2000,Python2.4a1,wxPython 2.5.1运行。[python调用shell的方法]


5.os.popen(command[,mode[,bufsize]])

举个栗子



>>> import os>>> p = os.popen("dir c:", 'r')>>> p.read()bla bla... <这里是dir正确的输出>>>> p.close()>>> p = os.popen("dir d:", 'r') # 电脑中没有D盘>>> p.read()''>>> p.close()1>>>



可以看出,popen方法通过p.read()获取终端输出,而且popen需要关闭close().当执行成功时,close()不返回任何值,失败时,close()返回系统返回值. 可见它获取返回值的方式和os.system不同。


6.使用commands模块

举个栗子



>>> import commands>>> commands.getstatusoutput('ls /bin/ls')(0, '/bin/ls')>>> commands.getstatusoutput('cat /bin/junk')(256, 'cat: /bin/junk: No such file or directory')>>> commands.getstatusoutput('/bin/junk')(256, 'sh: /bin/junk: not found')>>> commands.getoutput('ls /bin/ls')'/bin/ls'>>> commands.getstatus('/bin/ls')'-rwxr-xr-x 1 root 13352 Oct 14 1994 /bin/ls'



根据你需要的不同,commands模块有三个方法可供选择。getstatusoutput, getoutput, getstatus。


皮皮blog


7.Python文档中目前全力推荐第四个方法subprocess

当我们运行python的时候,我们都是在创建并运行一个进程。正如我们在Linux进程基础中介绍的那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序(fork,exec见Linux进程基础)。


subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。


使用subprocess包中的函数创建子进程的时候,要注意:


1) 在创建子进程之后,父进程是否暂停,并等待子进程运行。


2) 函数返回什么


3) 当returncode不为0时,父进程如何处理。


直接调用命令,返回值即是系统返回。


shell命令中有一些是shell的内建命令,这些命令必须通过shell运行,$cd。shell=True允许我们运行这样一些命令。shell=True表示命令最终在shell中运行。Python文档中出于安全考虑,不建议使用shell=True。建议使用Python库来代替shell命令,或使用pipe的一些功能做一些转义。:


例子



import subprocess
new_filename = '/tmp/b' filename = '/tmp/a' subprocess.call(['mv', filename, new_filename])
subprocess.call(['ls','-a', '/tmp'])

Note: lz试过这种方法调用mv指令如果加上shell=True就会出错:mv: missing file operand。但是下面的方式加上shell=True就不会出错。>>> subprocess.call("ls -l", shell=True)0>>> subprocess.call("exit 1", shell=True)1


1. 启动virtualenv是一个shell命令,要在shell中执行。否则出错:WindowsError: [Error 193] %1 is not a valid Win32 application


2. 然而virtualenv中执行的命令并不是shell命令,不是在shell中执行的,直接运行即可。否则出错:'scrapy' is not recognized as an internal or external command,operable program or batch file.


subprocess.call(r'../Scripts/activate', shell=True)
subprocess.call('scrapy crawl dmoz')

如果你更关注命令的终端输出,可以这样



>>> subprocess.check_output(["echo", "Hello World!"])'Hello World!/n'


>>> subprocess.check_output("exit 1", shell=True)


Traceback (most recent call last):...subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1



python3.5最新语法及示例


subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False)

>>> subprocess.run(["ls", "-l"])# doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null/n')

更复杂的命令使用,如


subprocess.run( "cat ~/files/DATASETS/tianchi/ccf_data_revised/ccf_online_stage1_train.csv | cut -d ',' -f 1 | uniq | sort -n > /tmp/1.txt", shell=True)


subprocess.run(r"mv '" + os.path.join(CA_DATASET_DIR, checkin_ca) + "' /tmp", shell=True)


参数使用

stdin和stdout

import subprocess
child1 = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE, cwd='/home/pipi')
child2 = subprocess.Popen(["cat"], stdin=child1.stdout, shell=True)
相当于将child1输出保存到一个文件,再使用child2的cat命令查看

input


The input argument is passed to Popen.communicate() and thus to thesubprocess’s stdin. If used it must be a byte sequence, or a string ifuniversal_newlines=True. When used, the internal Popen objectis automatically created with stdin=PIPE, and the stdin argument maynot be used as well.


input相当于一个文件中的内容,而不是命令的参数!

child2 = subprocess.run(["cat"], input = b'contents in a file', shell=True) # contents in a file
child2 = subprocess.run(["echo"], input = b'contents in a file', shell=True) # 无输出
使用代码中的变量

好像可以通过stdin输入代码中的变量,但是更简单的也可以直接使用下面的字符串连接实现

dir = '/home/pipi/files/DATASETS/tianchi/ccf_data_revised' train_filename = 'data_train2.txt' subprocess.run("cat " + train_filename + " | cut -d ',' -f 9 | sort| uniq -c", shell=True, cwd=dir)

指定子进程工作路径


Note: 上一条run修改当前路径对下一条run是没用的

dir = '/home/pipi/files/DATASETS/tianchi/ccf_data_revised' subprocess.run("cat data_train2.txt | cut -d ',' -f 9 | sort| uniq -c", shell=True, cwd=dir)

获取Popen的返回值及输出


import sys,os,subprocess,commandsfrom subprocess import Popen,PIPEp = Popen('python ' + path + '/getCurPath.py', stdout=PIPE, stderr=PIPE)p.wait()if(p.returncode == 0): print "stdout:%s" %p.stdout.read()

subprocess还有另一种更简单方法,效果一样,它会返回stdout


s = subprocess.check_output('ls -l', shell=True)


[subprocess — Subprocess management]


[Python标准库06 子进程 (subprocess包)]


[Python模块整理(三):子进程模块subprocess]


8.还有两种方法:os.spawn* 和 popen2.*。它们也可以完成同样的任务

Python和其他进程的管道通信方式--popen和popen2的比较


9.sh : Python subprocess interface

lz发现了一个相当不错的库amoffat/sh,可以用 Python 函数的语法去调用 shell 命令,sh 之于 subprocess 类似 requests 之于 urllib2。


pip3 install sh


sh库用来将shell命令作为函数导入到Python中。在bash中使用是非常实用的,但是在Python中不容易记住怎么使用(即递归搜索文件)。


使用示例


from sh import findfind("/tmp")/tmp/foo/tmp/foo/file1.json/tmp/foo/file2.json/tmp/foo/file3.json/tmp/foo/bar/file3.json


from sh import gitgit.clone("https://github.com/amoffat/sh")

from sh import ls, mv
new_filename = r'/tmp/b' filename = r'/tmp/a' try:mv(filename, new_filename)
except:pass print(ls('/tmp'))

[sh:sh 1.08 — sh v1.08 documentation]


[python sh库实现分析]


from:http://blog.csdn.net/pipisorry/article/details/46972171


ref:python中执行linux命令(调用linux命令)


6方法,python中执行shell命令


分享给朋友:
您可能感兴趣的文章:
随机阅读: