背景
調用系統命令,需要獲取執行之后的返回結果。
代碼
- shell=True
- 如果把shell設置成True,指定的命令會在shell里解釋執行。
- close_fds=True
- 如果把close_fds設置成True,*nix下會在開子進程前把除了0、1、2以外的文件描述符都先關閉。在 Windows下也不會繼承其他文件描述符。
- stdin stdout和stderr
- 分別表示子程序的標准輸入、標准輸出和標准錯誤。可選的值有PIPE或者一個有效的文件描述符(其實是個正整數)或者一個文件對象,還有None。
- subprocess.PIPE
- 如果是PIPE,則表示需要創建一個新的管道,如果是None,不會做任何重定向工作,子進程的文件描述符會繼承父進程的。另外,stderr的值還可以是STDOUT,表示子進程的標准錯誤也輸出到標准輸出。
- p.poll() : 定時檢查命令有沒有執行完畢,執行完畢后返回執行結果的狀態,沒有執行完畢返回None
# #!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
def run_cmd(_cmd):
"""
開啟子進程,執行對應指令,控制台打印執行過程,然后返回子進程執行的狀態碼和執行返回的數據
:param _cmd: 子進程命令
:return: 子進程狀態碼和執行結果
"""
p = subprocess.Popen(_cmd, shell=True, close_fds=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
_RunCmdStdout, _ColorStdout = [], '\033[1;35m{0}\033[0m'
while p.poll() is None:
line = p.stdout.readline().rstrip()
if not line:
continue
_RunCmdStdout.append(line)
print(_ColorStdout.format(line))
last_line = p.stdout.read().rstrip()
if last_line:
_RunCmdStdout.append(last_line)
print(_ColorStdout.format(last_line))
_RunCmdReturn = p.wait()
return _RunCmdReturn, b'\n'.join(_RunCmdStdout), p.stderr.read()
if __name__ == '__main__':
code, stdout, stderr = run_cmd('ping -c 3 baidu.com')
print('\nreturn:', code, '\nstdout:', stdout, '\nstderr:', stderr)
需要用到子進程功能的時候,直接導入該文件,調用run(...)
方法即可。