From : http://write.blog.youkuaiyun.com/postedit?ref=toolbar
preface: 忙于最近的任务,需要用到libsvm的一些命令,如在终端运行Java svm_train train_file model_file. Pythonsubset.py file train_num train_file test_file等命令,但file的准备又是通过python写好的,file需要是libsvm能够接受的格式,故用python写好特征,转为libsvm能够接受的格式,生成file,然后在终端调用训练。故想着直接在python代码里面直接运行终端的命令。博友博客描述得很详细,这里直接转载过来并做些注释了。
#=====================================================
一、os 模块
1.1.os模块的exec方法簇:
ipython交互界面中:
- In [1]: import os
- In [2]: os.exec
- os.execl os.execlp os.execv os.execvp
- os.execle os.execlpe os.execve os.execvpe
- In [2]: os.execl?
- Type: function
- String form: <function execl at 0xb73673e4>
- File: /home/shifeng/anaconda/lib/python2.7/os.py
- Definition: os.execl(file, *args)
- Docstring:
- execl(file, *args)
- Execute the executable file with argument list args, replacing the
- current process.
os.exec+Tab键智能提示可以看到有8个,help(os.execl)等可以找到其用法说明。
1.2.os模块的system方法
system方法会创建子进程运行外部程序,方法只返回外部程序的运行结果。0表示运行成功。
- In [10]: os.system("echo \"hello world\"")
- hello world
- Out[10]: 0
- In [11]: os.system("ls")
- all_roc_plot.py~ task1_feature_all2.py test.py test.sh ui_without_buy~
- scrapy_work test test.py~ test.sh~
- Out[11]: 0
- In [12]: os.system("cat test.sh")
- echo "hello world"
- Out[12]: 0
- In [13]: os.system("sh test.sh")
- hello world
- Out[13]: 0
1.3.os模块popen方法
popen方法能够得到shell命令的返回值,os.popen(cmd)后,需要再调用read()或者readlines()这两个命令。输出结果。
- In [14]: os.popen("ls")
- Out[14]: <open file 'ls', mode 'r' at 0xb67efd30>
- In [15]: os.popen("ls").read()
- Out[15]: 'all_roc_plot.py~\nscrapy_work\ntask1_feature_all2.py\ntest\ntest.py\ntest.py~\ntest.sh\ntest.sh~\nui_without_buy~\n'
- In [16]: os.popen("ls").readlines()
- Out[16]:
- ['all_roc_plot.py~\n',
- 'scrapy_work\n',
- 'task1_feature_all2.py\n',
- 'test\n',
- 'test.py\n',
- 'test.py~\n',
- 'test.sh\n',
- 'test.sh~\n',
- 'ui_without_buy~\n']
- In [17]: s = os.popen("ls").read()
- In [18]: for i in s.split("\n"):
- ....: print i
- ....:
- all_roc_plot.py~
- scrapy_work
- task1_feature_all2.py
- test
- test.py
- test.py~
- test.sh
- test.sh~
- ui_without_buy~
注意,read()或者readlines()后,其每个元素包含一个回车符\n。
二、commands模块
使用commands模块的getoutput方法,这种方法同popend的区别在于popen返回的是一个文件句柄,而本方法将外部程序的输出结果当作字符串返回,很多情况下用起来要更方便些。
主要方法:
* commands.getoutput(cmd) 只返回输出结果
* commands.getstatus(file) 返回ls -ld file的执行结果字符串,调用了getoutput,不建议使用此方法
- In [8]: import commands
- In [9]: commands.getoutput("ls")
- Out[9]: 'all_roc_plot.py~\nscrapy_work\ntask1_feature_all2.py\ntest\ntest.py\ntest.py~\ntest.sh\ntest.sh~\nui_without_buy~'
- In [10]: commands.getstatusoutput("ls")
- Out[10]:
- (0,
- 'all_roc_plot.py~\nscrapy_work\ntask1_feature_all2.py\ntest\ntest.py\ntest.py~\ntest.sh\ntest.sh~\nui_without_buy~')
三、subprocess模块
使用subprocess模块可以创建新的进程,可以与新建进程的输入/输出/错误管道连通,并可以获得新建进程执行的返回状态。使用subprocess模块的目的是替代os.system()、os.popen*()、commands.*等旧的函数或模块。
3.1.subprocess.call(["some_command","some_argument","another_argument_or_path"])
subprocess.call(command,shell=True)
使用subprocess模块可以创建新的进程,可以与新建进程的输入/输出/错误管道连通,并可以获得新建进程执行的返回状态。使用subprocess模块的目的是替代os.system()、os.popen*()、commands.*等旧的函数或模块。
- In [11]: from subprocess import call
- In [12]: call(["ls","-l"])
- 总用量 40
- -rw-rw-r-- 1 shifeng shifeng 3266 5月 3 14:14 all_roc_plot.py~
- drwxrwxr-x 6 shifeng shifeng 4096 6月 18 16:59 scrapy_work
- -rw-rw-r-- 1 shifeng shifeng 12786 6月 10 10:20 task1_feature_all2.py
- drwxrwxr-x 2 shifeng shifeng 4096 6月 8 11:36 test
- -rw-rw-r-- 1 shifeng shifeng 3649 6月 19 10:21 test.py
- -rw-rw-r-- 1 shifeng shifeng 255 6月 11 21:21 test.py~
- -rw-rw-r-- 1 shifeng shifeng 19 6月 25 19:49 test.sh
- -rw-rw-r-- 1 shifeng shifeng 0 6月 25 19:49 test.sh~
- -rw-rw-r-- 1 shifeng shifeng 0 4月 8 22:15 ui_without_buy~
- Out[12]: 0
- In [13]: from subprocess import Popen
- In [14]: Popen(["ls","-l"])
- Out[14]: <subprocess.Popen at 0xb67c91ac>
- In [15]: 总用量 40
- -rw-rw-r-- 1 shifeng shifeng 3266 5月 3 14:14 all_roc_plot.py~
- drwxrwxr-x 6 shifeng shifeng 4096 6月 18 16:59 scrapy_work
- -rw-rw-r-- 1 shifeng shifeng 12786 6月 10 10:20 task1_feature_all2.py
- drwxrwxr-x 2 shifeng shifeng 4096 6月 8 11:36 test
- -rw-rw-r-- 1 shifeng shifeng 3649 6月 19 10:21 test.py
- -rw-rw-r-- 1 shifeng shifeng 255 6月 11 21:21 test.py~
- -rw-rw-r-- 1 shifeng shifeng 19 6月 25 19:49 test.sh
- -rw-rw-r-- 1 shifeng shifeng 0 6月 25 19:49 test.sh~
- -rw-rw-r-- 1 shifeng shifeng 0 4月 8 22:15 ui_without_buy~
1、subprocess.call(command, shell=True)#会直接打印出结果。
2、subprocess.Popen(command, shell=True) 也可以是subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) 这样就可以输出结果了。如果command不是一个可执行文件,shell=True是不可省略的。shell=True意思是shell下执行command。
#========================以下转载============
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)
#==========================================
参考:
1.博友博客:http://blog.youkuaiyun.com/longerzone/article/details/17889969