Python 使用 subprocess 調用外部命令

從 Python 2.4 開始,Python 引入 subprocess 模塊來管理子進程,以取代一些舊模塊的方法:如os.systemos.spawnos.popenpopen2.*commands.*subprocess 不但可以調用外部的命令作爲子進程,而且可以連接到子進程的 input/output/error 管道,獲取相關的返回信息。

使用 subprocess 模塊

使用 Popen 類

class 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)

args 參數,指定要執行的外部程序。其值可以是字符串或者序列。

shell 默認爲 False。

在 Unix 下,shell=False 時, Popen 調用 os.execvp() 執行 args
指定的程序;shell=True 時,如果 args 是字符串,Popen 直接調用系統的 Shell 來執行 args 指定的程序,如果
args 是一個序列,則 args 的第一項是定義程序命令字符串,其它項是調用系統 Shell 時的附加參數。

在 Windows 下,不論 shell 的值如何,Popen 調用 CreateProcess() 執行 args
指定的外部程序。如果 args 是一個序列,則先用 list2cmdline() 轉化爲字符串,但需要注意的是,並不是 MS Windows
下所有的程序都可以用 list2cmdline 來轉化爲命令行字符串。

stdin、stdout、stderr 分別用於指定程序標準輸入、輸出、錯誤的 handle。其值可以爲 PIPE、file descriptor、文件對象、None。

以調用 Linux 下的 ping 命令爲例:

pingPopen = subprocess.Popen(args='ping -c4 www.google.cn', shell=True)

如果要取得 ping 的輸出信息:

pingPopen = subprocess.Popen(args='ping -c4 www.google.cn', shell=True, stdout=subprocess.PIPE)
print pingPopen.stdout.read()

外部程序是在一個子進程裏執行的,如果要等待該進程的結束,可以使用 wait():

pingPopen.wait()

wait() 方法會返回一個返回代碼。

又或者在創建 Popen 對象後調用 communicate() :

stdReturn = subprocess.Popen(args='ping -c4 www.google.cn', shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()

communicate() 返回一個 (stdout, sterr)。

使用 call() 和 check_all()

subprocess 模塊裏面有兩個方便的函數 call() 和 check_all(),可以直接調用來執行外部程序。

call(*popenargs, **kwargs)
check_call(*popenargs, **kwargs)

它們的參數列表跟 Popen 的構造函數參數列表一樣。返回一個 returncode。例如:

subprocess.call('ping -c4 www.google.cn',shel=True)


#!/usr/bin/env python

import subprocess
#print 'popen3:'

def external_cmd(cmd, msg_in=''):
    try:
        proc = subprocess.Popen(cmd,
                   shell=True,
                   stdin=subprocess.PIPE,
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE,
                  )
        stdout_value, stderr_value = proc.communicate(msg_in)
        return stdout_value, stderr_value
    except ValueError as err:
        # log("ValueError: %s" % err)
        return None, None
    except IOError as err:
        # log("IOError: %s" % err)
        return None, None

if __name__ == '__main__':
    stdout_val, stderr_val = external_cmd('ls -l')
    print 'Standard Output: %s' % stdout_val
    print 'Standard Error: %s' % stderr_val



參考資料

發佈了21 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章