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.system、os.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()
#!/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)
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