Python3执行CMD命令并获取输出内容(输出内容包含中文问题)

执行环境: Python3.6

os.popen

执行代码:

os.popen('allure')

抛出异常,未捕获到输出内容。
再次尝试代码:

os.popen("sc query state= all")

成功获取输出内容。
观察输出内容发现,异常语句的返回内容包含中文。
查看源码:

# Supply os.popen()
def popen(cmd, mode="r", buffering=-1):
    if not isinstance(cmd, str):
        raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
    if mode not in ("r", "w"):
        raise ValueError("invalid mode %r" % mode)
    if buffering == 0 or buffering is None:
        raise ValueError("popen() does not support unbuffered streams")
    import subprocess, io
    if mode == "r":
        proc = subprocess.Popen(cmd,
                                shell=True,
                                stdout=subprocess.PIPE,
                                bufsize=buffering)
        return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
    else:
        proc = subprocess.Popen(cmd,
                                shell=True,
                                stdin=subprocess.PIPE,
                                bufsize=buffering)
        return _wrap_close(io.TextIOWrapper(proc.stdin), proc)

标记断点发现采集输出时抛出异常,猜测应该是编码问题导致

subprocess.Popen

源码中os.popen直接调用了subprocess.Popen方法,在输出时抛出异常,这边也直接调用该方法并查看返回内容

popen = subprocess.Popen(['ping', 'www.baidu.com', '-n', '3'], stdout = subprocess.PIPE)
popen.wait()
lines = popen.stdout.readlines()

打上断点查看返回值:

: [b'\r\n', b'\xd5\xfd\xd4\xda Ping www.a.shifen.com [115.239.210.27] \xbe\xdf\xd3\xd0 32 \xd7\xd6\xbd\xda\xb5\xc4\xca\xfd\xbe\xdd:\r\n', b'\xc0\xb4\xd7\xd4 115.239.210.27 \xb5\xc4\xbb\xd8\xb8\xb4: \xd7\xd6\xbd\xda=32 \xca\xb1\xbc\xe4=9ms TTL=50\r\n', b'\xc0\xb4\xd7\xd4 115.239.210.27 \xb5\xc4\xbb\xd8\xb8\xb4: \xd7\xd6\xbd\xda=32 \xca\xb1\xbc\xe4=9ms TTL=50\r\n', b'\xc0\xb4\xd7\xd4 115.239.210.27 \xb5\xc4\xbb\xd8\xb8\xb4: \xd7\xd6\xbd\xda=32 \xca\xb1\xbc\xe4=9ms TTL=50\r\n', b'\r\n', b'115.239.210.27 \xb5\xc4 Ping \xcd\xb3\xbc\xc6\xd0\xc5\xcf\xa2:\r\n', b'    \xca\xfd\xbe\xdd\xb0\xfc: \xd2\xd1\xb7\xa2\xcb\xcd = 3\xa3\xac\xd2\xd1\xbd\xd3\xca\xd5 = 3\xa3\xac\xb6\xaa\xca\xa7 = 0 (0% \xb6\xaa\xca\xa7)\xa3\xac\r\n', b'\xcd\xf9\xb7\xb5\xd0\xd0\xb3\xcc\xb5\xc4\xb9\xc0\xbc\xc6\xca\xb1\xbc\xe4(\xd2\xd4\xba\xc1\xc3\xeb\xce\xaa\xb5\xa5\xce\xbb):\r\n', b'    \xd7\xee\xb6\xcc = 9ms\xa3\xac\xd7\xee\xb3\xa4 = 9ms\xa3\xac\xc6\xbd\xbe\xf9 = 9ms\r\n']

成功获取输出内容, 但数据类型是bytes,需要进行decode,windows的默认编码为GBK
将返回值进行decode

[line.decode('gbk') for line in lines]
: ['\r\n', '正在 Ping www.a.shifen.com [115.239.210.27] 具有 32 字节的数据:\r\n', '来自 115.239.210.27 的回复: 字节=32 时间=9ms TTL=50\r\n', '来自 115.239.210.27 的回复: 字节=32 时间=9ms TTL=50\r\n', '来自 115.239.210.27 的回复: 字节=32 时间=9ms TTL=50\r\n', '\r\n', '115.239.210.27 的 Ping 统计信息:\r\n', '    数据包: 已发送 = 3,已接收 = 3,丢失 = 0 (0% 丢失),\r\n', '往返行程的估计时间(以毫秒为单位):\r\n', '    最短 = 9ms,最长 = 9ms,平均 = 9ms\r\n']

成功获取正常输出。
进行简易封装:

def popen(cmd):
    try:
        popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        popen.wait()
        lines = popen.stdout.readlines()
        return [line.decode('gbk') for line in lines]
    except BaseException as e:
        return -1

DONE :)

你可能感兴趣的:(python)