python 執(zhí)行外部命令的幾種方式

os.system

  • 執(zhí)行的時(shí)候程序會(huì)打出cmd在linux上執(zhí)行的信息
  • 執(zhí)行命令成功返回為0,否則為1
  • 如果想獲取在cmd輸出的內(nèi)容,是沒(méi)辦法獲到的
t2 = os.system("1adb devices")
t3 = os.system("adb devices")
print(t2)  # 打印為1
print(t3) # 打印為0

subprocess.call

  • 取代os.system,但是也是無(wú)法獲取cmd輸出的內(nèi)容
import subprocess
t = subprocess.call('adb devices')
print(t) # 打印為0

os.popen

  • popen返回的是一個(gè)file對(duì)象,跟open打開(kāi)文件一樣操作了,r是以讀的方式打開(kāi)
output = os.popen('adb devices')
print(output.read()) # 得到List of devices attached

subprocess.Popen

  • subprocess模塊代替os.systemos.popen,能夠得到命令輸出的值

shell參數(shù)

  • linux下,當(dāng)shell=False(默認(rèn))時(shí),Popen使用os.execvp()來(lái)執(zhí)行子程序。args一般要是一個(gè)【列表】。如果args是個(gè)字符串的
    話(huà),會(huì)被當(dāng)做是可執(zhí)行文件的路徑,這樣就不能傳入任何參數(shù)了。
subprocess.Popen("cat test.txt", shell=True)
這是因?yàn)樗喈?dāng)于
subprocess.Popen(["/bin/sh", "-c", "cat test.txt"])

stdin stdout stderr 參數(shù)

  • 分別表示程序的標(biāo)準(zhǔn)輸入、輸出、錯(cuò)誤句柄。他們可以是PIPE,文件描述符或文件對(duì)象,也可以設(shè)置為None表示從父進(jìn)程繼承
  • 執(zhí)行結(jié)果使用管道輸出的實(shí)例:
pipe=subprocess.Popen("adb devices",shell=True,stdout=subprocess.PIPE).stdout
print(pipe.read()) # 得到值b'List of devices attached\r\n\r\n'
  • 執(zhí)行結(jié)果保存在文件實(shí)例
cmd = "adb shell ls /sdcard/ | findstr aa.png"  
fhandle = open(r"e:\aa.txt", "w")  
pipe = subprocess.Popen(cmd, shell=True, stdout=fhandle).stdout  
fhandle.close()
  • 子進(jìn)程的文本流控制
#!/usr/bin/env python

import subprocess

child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE)
out = child2.communicate()
print out
  • child1.stdout-->subprocess.PIPE
  • child2.stdin<--subprocess.PIPE
  • child2.stdout-->subprocess.PIPE
  • 相當(dāng)于將child1.stdout-->child2.stdin->child2.stdout->subprocess.PIPE
  • subprocess.PIPE實(shí)際上為文本流提供一個(gè)緩存區(qū)。child1的stdout將文本輸出到緩存區(qū),隨后child2的stdin從該P(yáng)IPE中將文本讀取走。child2的輸出文本也被存放在PIPE中,直到communicate()方法從PIPE中讀取出PIPE中的文本。
  • 要注意的是,communicate()是Popen對(duì)象的一個(gè)方法,該方法會(huì)阻塞父進(jìn)程,直到子進(jìn)程完成。
  • 我們還可以利用communicate()方法來(lái)使用PIPE給子進(jìn)程輸入:
import subprocess
child = subprocess.Popen(["cat"], stdin=subprocess.PIPE)
child.communicate("vamei") //()不為空,則寫(xiě)入subprocess.PIPE,為空,則從subprocess.PIPE讀取
  • subprocess.PIPE-->child.stdin
  • commiuncate相當(dāng)于寫(xiě)入subprocess.PIPE,然后child從subprocess.PIPE讀取
  • 利用python的subprocess模塊執(zhí)行外部命令, 并捕獲stdout, stderr的輸出
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('dir')
    print ('Standard Output: %s' % stdout_val)
    print ('Standard Error: %s' % stderr_val)
  • 得到命令的返回值,wait
p=subprocess.Popen("dir", shell=True)  
p.wait()
  • 但是Popen函數(shù)有一個(gè)缺陷,就是它是一個(gè)阻塞的方法。如果運(yùn)行cmd時(shí)產(chǎn)生的內(nèi)容非常多,函數(shù)非常容易阻塞住。解決辦法是不使用wait()方法,但是也不能獲得執(zhí)行的返回值了。

commands.getstatusoutput

  • 不介意使用,因?yàn)樵趐ython3中被廢棄
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容