python筆記65 - Python3 subprocess執行命令行獲取返回結果

2022-01-02 從零開始學自動化測試

收錄於話題 #python 85個

前言

subprocess 模塊允許我們啟動一個新進程,並連接到它們的輸入/輸出/錯誤管道,從而獲取返回值。
Popen 是 subprocess的核心,子進程的創建和管理都靠它處理。

subprocess.Popen

subprocess模塊定義了一個類:Popen

class Popen(object):
""" Execute a child program in a new process.

For a complete description of the arguments see the Python documentation.

Arguments:
args: A string, or a sequence of program arguments.

bufsize: supplied as the buffering argument to the open() function when
creating the stdin/stdout/stderr pipe file objects

executable: A replacement program to execute.

stdin, stdout and stderr: These specify the executed programs' standard
input, standard output and standard error file handles, respectively.

preexec_fn: (POSIX only) An object to be called in the child process
just before the child is executed.

close_fds: Controls closing or inheriting of file descriptors.

shell: If true, the command will be executed through the shell.

cwd: Sets the current directory before the child is executed.

env: Defines the environment variables for the new process.

universal_newlines: If true, use universal line endings for file
objects stdin, stdout and stderr.

startupinfo and creationflags (Windows only)

restore_signals (POSIX only)

start_new_session (POSIX only)

pass_fds (POSIX only)

encoding and errors: Text mode encoding and error handling to use for
file objects stdin, stdout and stderr.

Attributes:
stdin, stdout, stderr, pid, returncode
"""
_child_created = False # Set here since __del__ checks it

def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding=None, errors=None):
"""Create new Popen instance."""

常用參數:

args:

shell命令,可以是字符串或者序列類型(如:

str, list,元組)

bufsize:

緩衝區大小。

當創建標準流的管道對象時使用,默認-1。


 0:

不使用緩衝區
 1:

表示行緩衝,僅當universal_newlines=True時可用,也就是文本模式
 正數:

表示緩衝區大小
 負數:

表示使用系統默認的緩衝區大小。

stdin, stdout, stderr:

分別表示程序的標準輸入、輸出、錯誤句柄

preexec_fn:

只在 Unix 平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行之前被調用

shell:

如果該參數為 True,將通過作業系統的 shell 執行指定的命令。

cwd:

用於設置子進程的當前目錄。

env:

用於指定子進程的環境變量。

如果 env = None,子進程的環境變量將從父進程中繼承。

encoding:

設置編碼類型

使用示例

一個簡單示例,命令行執行pip

import subprocess
p = subprocess.Popen('pip -V',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)

# 輸出stdout
print(p.communicate()[0])

得到結果是byte類型的

b'pip 21.1.2 from e:\\python36\\lib\\site-packages\\pip (python 3.6)\r\r\n'

於是可以添加encoding參數utf-8

import subprocess
p = subprocess.Popen('pip -V',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding='utf-8'
)

# 輸出stdout
print(p.communicate()[0])

此時輸出

pip 21.1.2 from e:\python36\lib\site-packages\pip (python 3.6)

如果輸出有中文,會出現解碼異常
輸入java,正常情況是可以輸出中文的

import subprocess
p = subprocess.Popen('java',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding='utf-8'
)

# 輸出stdout
print(p.communicate()[0])

但是運行結果就會解碼異常

Traceback (most recent call last):
File "D:/tests.py", line 44, in <module>
print(p.communicate()[0])
File "E:\python36\lib\subprocess.py", line 830, in communicate
stdout = self.stdout.read()
File "E:\python36\lib\codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd3 in position 0: invalid continuation byte

原因是windows系統編碼是gb2312

windows解碼

知道windows系統的編碼後,設置對應的編碼,就可以正常解碼了

import subprocess
p = subprocess.Popen('java',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding='gb2312'
)

# 輸出stdout
print(p.communicate()[0])

得到

用法: java [-options] class [args...]
(執行類)
或 java [-options] -jar jarfile [args...]
(執行 jar 文件)
其中選項包括:
-d32 使用 32 位數據模型 (如果可用)
-d64 使用 64 位數據模型 (如果可用)
-server 選擇 "server" VM
默認 VM 是 server.

也可以在拿到輸出結果後decode解碼

import subprocess
p = subprocess.Popen('java',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
# 輸出stdout
result = p.communicate()[0]
print(result.decode('gb2312'))

執行python代碼,得到stdout內容

接下來寫一小段python代碼,看執行結果

# xx.py
print("hello world! 這段包含了中文")

使用subprocess.Popen執行,需設置encoding=』utf-8』

import subprocess
p = subprocess.Popen(['python', 'xx.py'],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding='utf-8'
)

# 輸出stdout
print(p.communicate()[0])

運行結果

hello world! 這段包含了中文

如果python代碼有語法異常

# xx.py
print("hello world! 這段包含了中文"x)

此時是可以輸出異常內容的

File "xx.py", line 1
print("hello world! 這段包含了中文"x)
^
SyntaxError: invalid syntax

Popen 對象方法

Popen 對象方法用到的幾個方法

poll(): 檢查進程是否終止,如果終止返回 returncode,否則返回 None。

wait(timeout): 等待子進程終止。

communicate(input,timeout): 和子進程交互,發送和讀取數據。

send_signal(singnal): 發送信號到子進程 。

terminate(): 停止子進程,也就是發送SIGTERM信號到子進程。

kill(): 殺死子進程。

發送 SIGKILL 信號到子進程。

其它方法參考菜鳥教程https://www.runoob.com/w3cnote/python3-subprocess.html

2021年第 9 期《python接口web自動化+測試開發》課程,10月17號開學!

加量不加價(新增postman, 贈送selenium和python基礎2個課

本期上課時間:10月17號-1月9號,每周六、周日晚上20:30-22:30

聯繫微信/QQ:283340479

相關焦點

  • 每周一個 Python 模塊|subprocess
    subprocess 模塊主要用於創建子進程,並連接它們的輸入、輸出和錯誤管道,獲取它們的返回狀態。通俗地說就是通過這個模塊,你可以在 Python 的代碼裡執行作業系統級別的命令,比如ipconfig、du -sh等。subprocess 模塊替代了一些老的模塊和函數,比如:os.system、os.spawn*等。
  • Python:subprocess模塊
    stdin, stdout, stderr:分別表示程序的標準輸入、輸出、錯誤句柄preexec_fn:只在 Unix 平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行之前被調用shell:如果該參數為 True,將通過作業系統的 shell 執行指定的命令。cwd:用於設置子進程的當前目錄。env:用於指定子進程的環境變量。如果
  • 程序媛筆記分享——python模塊之subprocess模塊
    subprocess模塊:專門用於py執行系統命令1. 簡單命令的執行# !("ls -l", shell=True)# 需注意,以上命令需要在linux系統下運行# call執行命令,返回狀態碼re1 = subprocess.call('ipconfig')print(re1)# check_all執行命令,如果執行狀態碼是 0 ,則返回0,否則拋異常re2 = subprocess.check_call
  • 四種執行python系統命令的方法
    四種執行python系統命令的方法四種執行python系統命令的方法一、os.system方法os.system(cmd)在子終端運行系統命令,可以獲取命令執行後的返回信息以及執行返回的狀態>>> import os>>> os.system('date')2018年 4月 8日 星期日 19時29分13秒 CST0  執行後返回兩行結果,第一行是結果, 第二行是執行狀態信息二、os.popen方法os.popen(cmd)不僅執行命令而且返回執行後的信息對象
  • Python 中的 Subprocess 模塊
    我們能從Python官方文檔裡讀到應該用subprocess 模塊來運行系統命令。subprocess模塊允許我們創建子進程,連接他們的輸入/輸出/錯誤管道,還有獲得返回值。subprocess模塊打算來替代幾個過時的模塊和函數,比如: os.system, os.spawn*, os.popen*, popen2.*命令。
  • python執行系統命令
    在python3中,推薦使用subprocess模塊來執行系統命令,基本用法如下>>> import subprocess>>> cmd = subprocess.run(['ls','-l'])>>> cmd.returncode0上述代碼中通過一個列表來記錄執行的命令,軟體名稱,選項,參數等都對應列表中的一個元素
  • Python執行系統命令的四種方法
    一、os.system方法 在子終端運行系統命令,可以獲取命令執行後的返回信息以及執行返回的狀態。執行後返回兩行結果,第一行是結果, 第二行是執行狀態信息,如果命令成功執行,這條語句返回0,否則返回1。 import os print(os.system('date'))
  • python調用外部命令的四種方式
    點擊關注「Python數據分析實例」
  • Python模塊學習:subprocess模塊
    Popen.returncode:獲取進程的返回值。如果進程還沒有結束,返回None。舉個例子(windows作業系統):假設桌面上有一個」ls.bat」的批處理文件,我們調用程序執行一下,」ls.bat」中只有一個命令」dir/w」。
  • 正確的使用python調用shell的姿勢
    stream.read()print output輸出123我們可以看到popen方法可以獲取命令執行後到輸入結果,但這還是有缺陷的,我們知道在linux裡面,有標準的0,1,2來代表標準輸入,輸出和錯誤,現在只有stdout沒有其他的兩個變量還是有限制的,如果仔細看python的方法,會發現popen還有popen2,popen3,popen4
  • Shell+Python混合編程的實現
    () 執行命令,返回命令的結果和執行狀態,0或者非0     res = subprocess.call(["ls","-l"])     res     #輸出0或者非0 - subprocess.check_call
  • subprocess.Popen實例應用
    在python的腳本中,有時候會調用shell命令來完成一些工作,在最早調用系統命令一般都是採用system()函數,這個後續會逐漸被替換了,因為
  • python筆記13-執行cmd指令(os.system和os.popen)
    蟲師科技的「python筆記」欄目,給大家分享基礎、實用、有趣的 Python 知識,讓更多的人懂Python!在用python處理數據的過程中,經常需要查找操作文件和路徑,這就依賴於os模塊。python調用Shell腳本,有兩種方法:os.system(cmd)或os.popen(cmd),前者返回值是腳本的退出狀態碼,後者的返回值是腳本執行過程中的輸出內容。實際使用時視需求情況而選擇。
  • 如何用 Python 執行單行命令
    例如:python -c "print('Hello World')"-c 之後,要用雙引號將命令包起來,import 以;結尾,命令用[]括起來,多行命令用多個[]。>chr_4ATCGTCaaaGANNAATGANGgggTA結果如下:>chr_1 13 10 7 10 4>chr_2 11 6 5 8 4>chr_3 10
  • python:argparse用於命令行參數解析
    argparse是python中內置的命令行解析模塊,內置於python,導入即可使用。
  • 用Python寫個在線Python的網站怎麼樣
    ,後來我發現一個事情,python裡面的subprocess算是一個很有趣的東西,他可以解釋python自己的代碼,之後就有個想法了,嘗試用subprocess去寫一個在線運行python的網站。ok,flask介紹完畢,我們下面進入正軌了,用subprocess來寫python了。
  • 徹底明白os.system、os.popen、subprocess.popen的用法和區別
    os.system 首先來看這個函數的文檔說明是說是在一個子shell中執行命令, 也即相當於執行手動在CMD窗口輸入的命令import osprint(os.system('cd ..'))print(os.system('mkdir new_folder')) os.popenpopen() 創建一個管道,通過fork一個子進程,然後該子進程執行命令。返回值在標準IO流中,該管道用於父子進程間通信。
  • Python黑客學習筆記:從HelloWorld到編寫PoC(上)
    打開終端,執行'python'命令打開Python解釋器:~$ pythonPython 2.7.3Type "help", "copyright", "credits" or "license" for more information.
  • Python-調用系統命令的方法
    os.system()該函數返回命令執行結果的返回值,system()函數在執行過程中進行了以下三步操作: 1、fork一個子進程; 2、在子進程中調用exec函數去執行命令; 3、在父進程中調用wait(阻塞)去等待子進程結束。返回0表示命令執行成功,其他表示失敗。
  • 序列比對在biopython中的處理
    讀取多序列比對結果 通過Bio.AlignIO模塊來對多序列比對結果進行讀寫,其中的parse方法用於從文件句柄中讀取多序列比對的內容,用法如下 該方法的返回值是一個迭代器,每次迭代,返回的是一個SeqRecord對象。 2.