Fork me on GitHub
Suzf  Blog

Python 执行Linux系统命令的N种方法

License: Attribution-NonCommercial-ShareAlike 4.0 International

本文出自 Suzf Blog。 如未注明,均为 SUZF.NET 原创。

转载请注明:http://suzf.net/post/409

前言:
很多时候我们会用到python去调用外部工具/命令去实现某种功能。
I. os
https://docs.python.org/2/library/os.html
os.system
执行流程
system(command) -> exit_status
Execute the command (a string) in a subshell.

# os.system() 是新起一个shell去干活的,对系统的开销比较大
# 仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息
# 无法控制,(如果调用的外部命令,挂死或者执行时间很长),主进程无法控制os.system(), 因为调用os.system(cmd)  调用进程会block, until os.system() 自己退出

In [30]: import os

In [31]: os.system('ls *.py')
check_drive_usage.py  diff_file.py  fcSpider.py  fedspider.py  get_host_list.py  test.py  while.py
Out[31]: 0

os.popen
执行流程
popen(command [, mode='r' [, bufsize]]) -> pipe
Open a pipe to/from a command returning a file object.

# 该方法不但执行命令还返回执行后的信息对象
# 好处在于:将返回的结果赋于一变量,便于程序的处理

In [32]: py = os.popen('ls *py').readlines()

In [33]: print py
['check_drive_usage.py\n', 'diff_file.py\n', 'fcSpider.py\n', 'fedspider.py\n', 'get_host_list.py\n', 'test.py\n', 'while.py\n']

 

II. commands
https://docs.python.org/2/library/commands.html
常用的主要有两个方法:getoutput和getstatusoutput

In [40]: import commands

In [41]: commands.getoutput('ls *.py')
Out[41]: 'check_drive_usage.py\ndiff_file.py\nfcSpider.py\nfedspider.py\nget_host_list.py\ntest.py\nwhile.py'

In [41]: commands.getstatusoutput('ls *py')
Out[41]:
(0,
 'check_drive_usage.py\ndiff_file.py\nfcSpider.py\nfedspider.py\nget_host_list.py\ntest.py\nwhile.py')

 

III. subprocess  [ 推荐使用 ]
https://docs.python.org/2/library/subprocess.html
http://python.usyiyi.cn/python_278/library/subprocess.html
# 运用对线程的控制和监控,将返回的结果赋于一变量,便于程序的处理
# 会自动地加载系统环境变量。
subprocess模块主要用于替代以下几个模块函数
os.system
os.spawn*
os.popen*
popen2.*
commands.*
相对应的subprocess 模块里有 call 函数和 popen 函数 。

1、subprocess.call
call 函数的用法如下:
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
可以看出,相对于os模块中的函数,这里可以指定的选项更多。

In [64]: import subprocess

In [65]: subprocess.call('ls *py ',shell=False)
check_drive_usage.py  diff_file.py  fcSpider.py  fedspider.py  get_host_list.py  test.py  while.py
Out[65]: 0

交互式模式下,call 也会有returncode 0 输出,不过在py文件里执行时,ruturn的结果并不会将最后的 0 输出。不过在使用call 函数时,需要注意后面的几个参数:

    开启shell=True是不安全的
    Using shell=True can be a security hazard. See the warning under Frequently Used Arguments for details.
    Note:
    尽量不要启用标准输出和标准错误输出需要管道,call有可能会导致子进程死锁。如需管道时,请使用Popen函数
    Do not use stdout=PIPE or stderr=PIPE with this function as that can deadlock based on the child process output volume. Use Popen with the communicate() method when you need pipes.

subprocess.call 主要用于替换 os.system ,具体如下:

In [66]: subprocess.call('date')
Thu Oct 29 16:02:24 CST 2015
Out[66]: 0

sub.process.Popen的用法如下:

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)

eg:

In [67]: import subprocess

In [68]: p = subprocess.Popen('ls *.py', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

In [69]: print p.stdout.readlines()
['check_drive_usage.py\n', 'diff_file.py\n', 'fcSpider.py\n', 'fedspider.py\n', 'get_host_list.py\n', 'test.py\n', 'while.py\n']

 

更多内容请移步官网 https://docs.python.org

 

「一键投喂 软糖/蛋糕/布丁/牛奶/冰阔乐!」

Suzf Blog

(๑>ڡ<)☆ 谢谢 ~

使用微信扫描二维码完成支付