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

时间:2024-11-10 14:10:20
执行环境: Python3.6

执行代码:

('allure')

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

("sc query state= all")

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

# Supply ()
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 = (cmd,
                                shell=True,
                                stdout=,
                                bufsize=buffering)
        return _wrap_close((), proc)
    else:
        proc = (cmd,
                                shell=True,
                                stdin=,
                                bufsize=buffering)
        return _wrap_close((), proc)

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

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

popen = (['ping', '', '-n', '3'], stdout = )
()
lines = ()

打上断点查看返回值:

<class 'list'>: [b'\r\n', b'\xd5\xfd\xd4\xda Ping  [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

[('gbk') for line in lines]
<class 'list'>: ['\r\n', '正在 Ping  [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 = (cmd, stdout=)
        ()
        lines = ()
        return [('gbk') for line in lines]
    except BaseException as e:
        return -1

DONE :)