python執行系統命令的方法:os.system(), os.popen(), subprocess.Popen()


一、os.system方法

優點:使用方法簡單。

缺點:1)返回值只包含命令執行狀態,不包含命令輸出。2)阻塞

1)返回值
執行操作系統的命令,將結果輸出到屏幕,只返回命令執行狀態(0:成功,非 0 : 失敗)
>>> result = os.system('pwd')
/root
>>> result
0
2)阻塞
在執行os.system函數的時候通常會阻塞它的調用者,等待所啟動的命令行程序退出。
在Linux平台上 只需要在命令末尾加上shell后台運算符&即可。

二、os.popen方法

執行操作系統的命令,會將結果保存在file對象當中,可以用read()、readlines()等方法讀取出來

優點:執行簡單,返回結果包含命令的輸出。

import os
result = os.popen('cat /etc/passwd')
print(result.read())
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

 

三、commands模塊

關於 commands 的說明:

  1. python 3.0 之后移除此命令,使用 subprocess代替;
  2. python 3.x 使用 subprocess 創建一個新進程;

 

四、subprocess模塊

Subprocess是一個功能強大的子進程管理模塊,是替換

  • os.system
  • os.spawn*
  • os.popen*
  • popen2.*
  • commands.*

等方法的一個模塊。

當執行命令的參數或者返回中包含了中文文字,那么建議使用subprocess。

1、subprocess.run()

1.1、 python 解析傳入命令的每個參數的列表

1.2、需要交給Linux shell自己解析,則:傳入命令字符串,shell=True

>>> res = subprocess.run("cd",shell=True,stdout=subprocess.PIPE)
>>> res.stdout
b'C:\\Users\\wangwuhui\\Desktop\r\n'

2、subprocess.call() 

相當於os.system()

3、subprocess.check_call()

執行命令,返回結果和狀態,正常為0 ,執行錯誤則拋出異常

4、subprocess.getstatusoutput()

接受字符串形式的命令,返回 一個元組形式的結果,第一個元素是命令執行狀態,第二個為執行結果

4.1、執行正確

>>> result = subprocess.getstatusoutput("pwd")
>>> result
(0, '/root')

4.2、執行錯誤

>>> result = subprocess.getstatusoutput("pwdd")
>>> result
(127, '/bin/sh: pwdd: command not found')

 

5、subprocess.getoutput()

接受字符串形式的命令,返回執行結果

5.1、執行命令正常

>>> result = subprocess.getoutput("pwd")
>>> result
'/root'

5.2、執行命令出錯

>>> result = subprocess.getoutput("pwdd")
>>> result
'/bin/sh: pwdd: command not found'
>>>

 

6、subprocess.check_output()

 

 7、subprocess.Popen()

其實前面subprocess使用的方法,都是對subprocess.Popen的封裝,下面我們就來看看這個Popen方法。

7.1、stdout

標准輸出

>>> res = subprocess.Popen("ls /tmp/yum.log", shell=True, stdout=subprocess.PIPE) # 使用管道

>>> res.stdout.read()  # 標准輸出
b '/tmp/yum.log\n'
res.stdout.close()  # 關閉

 

7.2、stderr

標准錯誤

>>> import subprocess

>>> res = subprocess.Popen( "lm -l" ,shell = True ,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
# 標准輸出為空
>>> res.stdout.read()
b''
#標准錯誤中有錯誤信息
>>> res.stderr.read()
b '/bin/sh: lm: command not found\n'

注意:上面的提到的標准輸出都為啥都需要等於subprocess.PIPE,這個又是啥呢?原來這個是一個管道,這個需要畫一個圖來解釋一下

 

 

7.3、poll()

定時檢查命令有沒有執行完畢,執行完畢后返回執行結果的狀態,沒有執行完畢返回None

>>> res = subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> print(res.poll())
None
>>> print(res.poll())
None
>>> print(res.poll())
0

 

7.4、wait()

等待命令執行完成,並且返回結果狀態

>>> obj = subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

>>> obj.wait()
# 中間會一直等待
0

 

7.5、terminate()

結束進程

import subprocess

>>> res = subprocess.Popen( "sleep 20;echo 'hello'" ,shell = True ,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
>>> res.terminate() # 結束進程
>>> res.stdout.read()
b''

 

7.6、pid

獲取當前執行子shell的程序的進程號

import subprocess

>>> res = subprocess.Popen( "sleep 5;echo 'hello'" ,shell = True ,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
>>> res.pid # 獲取這個linux shell 的 進程號
2778

 

7.7、communicate

該方法可用來與進程進行交互,比如發送數據到stdin,從stdout和stderr讀取數據,直到到達文件末尾。

例子1:子進程中使用錄屏軟件。 

#coding:utf-8

import time
import os
import datetime
import subprocess

def live_video():
    file_name = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S.mp4')
# 開啟錄屏 live_video
= subprocess.Popen('ffmpeg -f gdigrab -i desktop -vcodec libx264 -pix_fmt yuv420p {} -y'.format(file_name),shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE) time.sleep(10) # 錄制10秒 live_video.stdin.write('q'.encode("GBK")) # 發送命令,停止錄屏 live_video.communicate() # 發送數據到標准輸入 live_video()

 

例子2:子進程中使用Python

print("***Popen對象stdin寫入功能:使用communicate輸出")
p4 = subprocess.Popen(["python"], stdout=subprocess.PIPE,
                          stdin=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
p4.stdin.write("print('hello')")
output = p4.communicate()
print(output)       # 結果:('hello\n', '')

 

例子3:子進程中切換賬戶

    p4 = subprocess.Popen("/opt/work/plsh/plsh",stdout=subprocess.PIPE,stdin=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True,shell=True)
    p4.stdin.write("test\n") # 輸入用戶名
    p4.stdin.write("lalala.test\n") # 輸入密碼
    p4.stdin.write("show capture\n") #切換賬戶后,執行命令
    output = p4.communicate()[0]

 

  

 

更多例子參考:

https://www.jianshu.com/p/430c411160f8


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM