使用python的subprocess模塊啓動exe文件

        hello, 你們好,又到了小猿爲你們分享技術的時間了.
css

近期拿到一個測試案例, 其中有一塊是須要在測試案例中啓動一個exe文件,而且在達到某個條件以後在shutdown掉,因而我就開始找尋解決方案(沒錯,百度以及谷歌),可是找到的試驗起來要麼達不到咱們預期的效果,要麼就是由於權限的緣由能刪除掉,總之三個字, 煩死了.python

好在最後找到了使用subprocess開啓進程,使用命令 "taskkill /F /t /IM a.exe"命令結束進程,結果出乎的順利.linux

        雖然有點不三不四,可是目前而言,這個是最好的結果了.就先這樣用着吧,談到subprocess, 今天我們就分享一點關於subprocess模塊相關的知識吧.   shell

關於subprocess與Popen()django

        subprocess的做用是能夠在當前程序中執行其餘程序或者命令緩存

        suprocess模塊以及提供的Popen類,在這裏介紹一下如何使用它在進程中建立一個新的子進程,還會有其餘的方法與屬性,它們在某些狀況下很是方便和高效。ruby

        首先是subprocess.Popen 類bash

        經過調用微信

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)

使用其建立而且返回一個子進程,並在這個進程中執行指定的程序.數據結構

這個能夠經過裏面的參數詳細制定子進程的環境,可是隻有一個參數是必須的,即位置參數,不用着急,下面詳細介紹剩餘的參數

參數介紹:

  • args: 要執行的命令或者可執行文件的絕對路徑,是一個由字符串組成的序列(一般指的是列表), 第一個元素是可執行程序的路徑,剩下的是傳遞給這個程序的參數,若是隻是單獨的運行這個程序, 只是一個單純的字符串就行,可是這個字符串必須是能使subprocess找到該指定文件.

  • bufsize:控制stdin, stdout, stderr 等參數指定的文件的緩衝,和打開文件的 open()函數中的參數 bufsize 含義相同。

  • executable: 這是替代參數args做爲可執行程序的,若是該參數不是None的話.

  • stdin:指定子進程的標準輸入.

  • stdout:指定子進程的標準輸出.

  • stderr:指定子進程的標準錯誤輸出.

    對於 stdin, stdout和 stderr 而言,若是他們是 None(默認狀況),那麼子進程使用和父進程相同的標準流文件。

  • preexec_fn:默認是None,不然必須是一個函數或者可調用對象,在子進程中首先執行這個函數,而後再去執行爲子進程指定的程序或Shell。

  • close_fds:布爾型變量,爲 True 時,在子進程執行前強制關閉全部除 stdin,stdout和stderr外的文件;

  • shell:布爾型變量,明確要求使用shell運行程序,與參數 executable 一同指定子進程運行在什麼 Shell 中——若是executable=None 而 shell=True,則使用 /bin/sh 來執行 args 指定的程序;也就是說,Python首先起一個shell,再用這個shell來解釋指定運行的命令。

  • cwd:表明路徑的字符串,指定子進程運行的工做目錄,要求這個目錄必須存在;

  • env:字典,鍵和值都是爲子進程定義環境變量的字符串;

  • universal_newline:布爾型變量,爲 True 時,stdoutstderr 以通用換行(universal newline)模式打開,

  • startupinfo:見下一個參數;

  • creationfalgs:最後這兩個參數是Windows中才有的參數,傳遞給Win32的CreateProcess API調用。

        這裏的建立子進程和linux建立子進程相似,父進程建立完子進程以後,並不會自動等待子進程, 父進程在子進程結束以前退出會致使該子進程成爲孤兒進程, 最終由init進程接管,負責終止後的回收工做.

        若是子進程先於父進程終止,可是父進程終止前沒有進行最後的回收工做,子進程殘留數據結構被稱爲殭屍進程,數量大的話會耗費系統資源,所以父進程等待和回收子進程是有必要的,除非確認可以本身比子進程先退出,從而將回收工做過渡給init進程,關於等待和回收子進程的函數就是wait()函數.固然另外一個更簡便的方法是使用命令 'taskkill /F /t /IM a.exe'使用os.system的命令能夠刪除,不會出現權限不夠關不了的問題,可是有點粗暴.

下面是在linux環境下執行的命令:

[root@localhost ~]# pythonPython 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import subprocess>>> p = subprocess.Popen('ls -l',shell=True)>>> total 28drwxr-xr-x. 2 root root 6 Feb 14 2019 123-rw-r--r--. 1 root root 800 Feb 18 2019 --all-databases-rw-------. 1 root root 1301 Jan 26 2019 anaconda-ks.cfg-rwxr-xr-x 1 root root 164 Sep 8 21:28 bash.shdrwxr-xr-x. 3 root root 58 Feb 15 2019 django115drwxr-xr-x. 3 root root 56 Feb 15 2019 django2drwxr-xr-x. 9 root root 4096 Apr 16 2019 Envsdrwxr-xr-x. 2 root root 40 Dec 30 23:05 myfile-rwxrwxrwx. 1 root root 22 Apr 22 2019 myshell-rw-r--r--. 1 root root 0 Apr 23 2019 myso-rw-r--r--. 1 root root 403 Feb 15 2019 requirements.txt-rw-r--r--. 1 root root 26 May 11 2019 test.txtp = >>> p.returncode>>> p.wait()0>>> p.returncode0

下面來看一下Popen對象的方法和屬性

方法:

  1. p.poll()  用於檢查子進程P是否終止,返回p.returncode屬性.

  2. p.wait() 等待子進程,返回p.returncode屬性 0 表明該子進程已經結束,注意,使用該方法會當即阻塞父進程,直到子進程結束

  3. p.send_signal(signal) 向子進程發送信號

  4. p.communicate(input=None), 和子進程進行交互式交流,將參數中的數據發送到子進程的stdin, 同時從子進程的stdout和stderr讀取數據,直到EOF,該方法也會阻塞父進程.

    注意點:子進程發送給的父進程的數據是緩存在內存中的,所以該方法不適合交換過大的數據, 在這這種方法只能經過管道和本身的子進程通訊,即建立子進程的參數stdin=subprocess.PIPE 才能經過該方法進行消息發送.

  5. p.terminate() 終止子進程

  6. p.kill() 殺死子進程

Popen對象的屬性

如今先假設p是Popen的子進程,p的屬性包括如下幾項

  1. p.pid 該子進程的pid

  2. p.returncode  表示該子進程的返回狀態,有多種狀況

    • None - 子進程還沒有結束

    • 0 - 正常退出

    • 大於0 - 子進程異常退出

    • 小於 0 - 子進程被信號幹掉

  3. p.stdin, p.stdout, p.stderr  子進程對應的一些初始文件,若是在開啓子進程時傳入的參數有subprocess.PIPE,則這個屬性是一個包裹了這個管道的file對象.

使用subprocess模塊定義的異常

exception subprocess.CalledProcessError
  • 出現該異常的條件:調用check_call() 或 check_output() ,子進程的退出狀態不爲 0 時。

    該異常包含如下信息:

    • returncode:子進程的退出狀態;

    • cmd:建立子進程時指定的命令;

    • output:若是是調用 check_output() 時拋出的該異常,這裏包含子進程的輸出,不然該屬性爲None。

        關於該模塊的內容,小猿暫時就先介紹到這吧.但願能給你帶來點些許的啓發.也歡迎你們分享以及提出寶貴意見,您的意見我會所有查看並認真思考而且回覆的呦.


本文分享自微信公衆號 - IT民工技術之路(python_er)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索