Python的subprocess模塊提供了一種在Python中調用外部命令的方法。它允許您在Python程序中啟動新進程,連接到它們的輸入/輸出/錯誤管道,并等待它們完成。
常用用法
下面是一些subprocess模塊的常用用法:
- 運行外部命令并獲取輸出:
import subprocess
output = subprocess.check_output(["ls", "-l"])
print(output.decode())
- 運行外部命令并獲取返回值:
import subprocess
return_code = subprocess.call(["ls", "-l"])
print(return_code)
- 運行外部命令并將輸出重定向到文件:
import subprocess
with open("output.txt", "w") as f:
subprocess.call(["ls", "-l"], stdout=f)
- 運行外部命令并將輸入從文件中讀?。?/li>
import subprocess
with open("input.txt", "r") as f:
subprocess.call(["grep", "hello"], stdin=f)
- 運行外部命令并將輸入從Python程序中提供:
import subprocess
subprocess.call(["grep", "hello"], input=b"hello world
")
- 運行外部命令并捕獲標準錯誤:
import subprocess
try:
subprocess.check_output(["ls", "-l", "/nonexistent"])
except subprocess.CalledProcessError as e:
print(e.stderr.decode())
- 運行外部命令并等待它完成:
import subprocess
p = subprocess.Popen(["sleep", "5"])
p.wait()
print("Done")
以上是subprocess模塊的一些常用用法,更多詳細信息請參考Python官方文檔。
創(chuàng)建一個新的進程
Python的subprocess模塊中的Popen函數(shù)用于創(chuàng)建一個新的進程,并與其進行交互。Popen函數(shù)的語法如下:
subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None,
universal_newlines=False, startupinfo=None, creationflags=0)
參數(shù)說明:
- args:要執(zhí)行的命令,可以是一個字符串或一個列表。如果是一個字符串,則會被解釋為一個shell命令;如果是一個列表,則第一個元素是要執(zhí)行的命令,后面的元素是命令的參數(shù)。
- bufsize:緩沖區(qū)大小,默認為-1,表示使用系統(tǒng)默認值。
- executable:要執(zhí)行的可執(zhí)行文件的路徑,默認為None,表示使用系統(tǒng)默認的可執(zhí)行文件。
- stdin、stdout、stderr:分別表示標準輸入、標準輸出、標準錯誤輸出的文件描述符。默認為None,表示使用父進程的標準輸入、標準輸出、標準錯誤輸出。
- preexec_fn:在子進程執(zhí)行前被調用的可執(zhí)行對象,可以是一個函數(shù)或一個可調用對象。默認為None。
- close_fds:如果為True,則在子進程中關閉所有文件描述符。默認為True。
- shell:如果為True,則將args作為一個shell命令執(zhí)行。默認為False。
- cwd:子進程的當前工作目錄。默認為None,表示使用父進程的當前工作目錄。
- env:子進程的環(huán)境變量。默認為None,表示使用父進程的環(huán)境變量。
- universal_newlines:如果為True,則將stdin、stdout、stderr的數(shù)據(jù)以文本模式處理。默認為False。
- startupinfo:用于指定子進程的一些啟動信息,如窗口大小、標題等。默認為None。
- creationflags:用于指定子進程的一些標志,如CREATE_NEW_CONSOLE、CREATE_NEW_PROCESS_GROUP等。默認為0。
Popen函數(shù)返回一個Popen對象,可以通過該對象的方法和屬性與子進程進行交互,如:
- communicate(input=None, timeout=None):與子進程進行交互,發(fā)送input數(shù)據(jù)并等待子進程執(zhí)行完畢。如果timeout不為None,則在指定時間內等待子進程執(zhí)行完畢。
- poll():檢查子進程是否已經結束,如果已經結束則返回子進程的退出狀態(tài)碼,否則返回None。
- wait(timeout=None):等待子進程執(zhí)行完畢,并返回子進程的退出狀態(tài)碼。如果timeout不為None,則在指定時間內等待子進程執(zhí)行完畢。
- send_signal(signal):向子進程發(fā)送信號。
- terminate():向子進程發(fā)送SIGTERM信號,終止子進程。
- kill():向子進程發(fā)送SIGKILL信號,強制終止子進程。
- pid:子進程的進程ID。
- returncode:子進程的退出狀態(tài)碼。
示例代碼:
import subprocess
# 執(zhí)行一個簡單的命令
p = subprocess.Popen('ls -l', shell=True)
p.wait()
# 執(zhí)行一個帶參數(shù)的命令
p = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
output, error = p.communicate()
print(output.decode())
# 執(zhí)行一個長時間運行的命令,并在指定時間內等待其執(zhí)行完畢
p = subprocess.Popen('sleep 10', shell=True)
try:
p.wait(timeout=5)
except subprocess.TimeoutExpired:
p.kill()
與子進程進行交互
communicate()
是subprocess
模塊中的一個方法,用于與子進程進行交互。它會向子進程的標準輸入發(fā)送數(shù)據(jù),并等待子進程完成任務后獲取其標準輸出和標準錯誤輸出。
communicate()
方法的語法如下:
stdout, stderr = subprocess.communicate(input=None, timeout=None)
其中,input
參數(shù)是要發(fā)送給子進程的數(shù)據(jù),可以是字符串或字節(jié)流。如果不需要向子進程發(fā)送數(shù)據(jù),則可以將其設置為None
。timeout
參數(shù)是等待子進程完成任務的超時時間,單位為秒。如果子進程在超時時間內未完成任務,則會拋出TimeoutExpired
異常。
communicate()
方法會返回一個元組,其中第一個元素是子進程的標準輸出,第二個元素是子進程的標準錯誤輸出。如果子進程沒有輸出,則對應的元素為None
。
下面是一個使用communicate()
方法的示例:
import subprocess
# 執(zhí)行命令
p = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 獲取子進程的輸出
stdout, stderr = p.communicate()
# 輸出子進程的標準輸出和標準錯誤輸出
print(stdout.decode('utf-8'))
print(stderr.decode('utf-8'))
在上面的示例中,我們使用Popen()
方法創(chuàng)建了一個子進程,并將其標準輸出和標準錯誤輸出分別重定向到管道中。然后,我們使用communicate()
方法等待子進程完成任務,并獲取其標準輸出和標準錯誤輸出。最后,我們將其轉換為字符串并輸出。
執(zhí)行結果解析成json格式
可以使用Python的json模塊將subprocess執(zhí)行結果解析成json格式。
假設subprocess執(zhí)行的命令是獲取系統(tǒng)信息的命令,如下所示:
import subprocess
cmd = "systeminfo"
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
執(zhí)行結果保存在result變量中,可以使用json模塊將其解析成json格式,如下所示:
import json
output = result.stdout.decode('utf-8')
json_output = json.loads(output)
其中,result.stdout是subprocess執(zhí)行結果的標準輸出,使用decode方法將其轉換成字符串類型。然后使用json.loads方法將字符串解析成json格式。
解析后的json格式可以按照需要進行處理和使用。
檢查子進程是否已經結束
在subprocess中,poll()方法用于檢查子進程是否已經結束。如果子進程已經結束,poll()方法會返回子進程的退出狀態(tài)碼。如果子進程還在運行,poll()方法會返回None。
下面是一個使用poll()方法的示例:
import subprocess
# 啟動子進程
p = subprocess.Popen(['ls', '-l'])
# 檢查子進程是否已經結束
while p.poll() is None:
print('子進程還在運行...')
# 子進程已經結束,獲取退出狀態(tài)碼
print('子進程已經結束,退出狀態(tài)碼為:', p.returncode)
在上面的示例中,我們啟動了一個子進程來執(zhí)行l(wèi)s命令,然后使用poll()方法檢查子進程是否已經結束。如果子進程還在運行,就會一直輸出“子進程還在運行…”,直到子進程結束。當子進程結束后,我們使用returncode屬性獲取子進程的退出狀態(tài)碼,并輸出到控制臺。
等待子進程結束
在subprocess模塊中,wait()方法用于等待子進程結束并返回狀態(tài)碼。它會阻塞當前進程,直到子進程結束為止。
wait()方法的語法如下:
status = subprocess.Popen.wait(self, timeout=None, endtime=None)
其中,timeout參數(shù)表示等待子進程結束的最長時間,單位為秒;endtime參數(shù)表示等待子進程結束的最晚時間,是一個時間戳。
如果子進程已經結束,wait()方法會立即返回狀態(tài)碼;如果子進程還在運行,wait()方法會阻塞當前進程,直到子進程結束為止。
wait()方法返回的狀態(tài)碼是一個整數(shù),表示子進程的退出狀態(tài)。如果子進程正常結束,狀態(tài)碼為0;如果子進程異常結束,狀態(tài)碼為一個非零值,具體的值表示異常的類型。
判斷是否執(zhí)行成功
在Python中,可以使用subprocess模塊的returncode屬性來判斷子進程是否執(zhí)行成功。如果子進程成功執(zhí)行,returncode屬性的值為0;如果子進程執(zhí)行失敗,returncode屬性的值為非零。可以通過以下代碼來實現(xiàn):文章來源:http://www.zghlxwxcb.cn/news/detail-477186.html
import subprocess
# 執(zhí)行命令
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 判斷是否執(zhí)行成功
if result.returncode == 0:
print('執(zhí)行成功')
else:
print('執(zhí)行失敗')
在上面的代碼中,我們使用subprocess.run()方法執(zhí)行了一個ls -l命令,并將結果保存在result變量中。然后,我們通過判斷result.returncode的值來判斷子進程是否執(zhí)行成功。如果returncode的值為0,則表示執(zhí)行成功;否則,表示執(zhí)行失敗。文章來源地址http://www.zghlxwxcb.cn/news/detail-477186.html
到了這里,關于使用python的subprocess執(zhí)行命令、交互、等待、是否結束、解析JSON結果的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!