Python | 用Python获取Windows控制台输出

1 os模块实现

import os

cmd = 'ping baidu.com'
r = os.popen(cmd)
for line in r.readlines():
    print (line)

以上代码利用os.popen()指令获取了控制台的输出内容。

结果示例:

正在 Ping baidu.com [123.125.115.110] 具有 32 字节的数据:

来自 123.125.115.110 的回复: 字节=32 时间=50ms TTL=44

来自 123.125.115.110 的回复: 字节=32 时间=51ms TTL=44

来自 123.125.115.110 的回复: 字节=32 时间=50ms TTL=44

来自 123.125.115.110 的回复: 字节=32 时间=52ms TTL=44



123.125.115.110 的 Ping 统计信息:

    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),

往返行程的估计时间(以毫秒为单位):

    最短 = 50ms,最长 = 52ms,平均 = 50ms

辨析os.system与os.popen函数

  • 两个函数均执行参数中的系统指令
  • os.system指令返回值为系统的退出状态码
  • os.popen指令返回值为控制台的输出内容

参考:用Python获取命令行输出


2 subprocess模块实现

PEP324标准中,提出了用subprocess模块取代os.systemos.popen等函数的功能。在实践中,subprocess模块也比os.popen等函数有更好的表现,特别是在多线程开发中。

该模块中最重要的类是Popen类

class Popen(args, bufsize=0, executable=None,
            stdin=None, stdout=None, stderr=None,
            preexec_fn=None, close_fds=False, shell=False,
            cwd=None, env=None, universal_newlines=False,
            startupinfo=None, creationflags=0):

常用的参数:

  • args should be a string, or a sequence of program arguments. The program to execute is normally the first item in the args sequence or string, but can be explicitly set by using the executable argument.

  • stdin, stdout and stderr specify the executed programs' standard input, standard output and standard error file handles, respectively. Valid values are PIPE, an existing file descriptor (a positive integer), an existing file object, and None. PIPE indicates that a new pipe to the child should be created. With None, no redirection will occur; the child's file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the applications should be captured into the same file handle as for stdout.

  • If shell is true, the specified command will be executed through the shell.

  • If cwd is not None, the current directory will be changed to cwd before the child is executed. ( cwd means current working directory)

  • If env is not None, it defines the environment variables for the new process.

常用的方法:

  • poll(): Check if child process has terminated. Returns returncode attribute.

  • wait(): Wait for child process to terminate. Returns returncode attribute.

  • communicate(input=None)
    Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional stdin argument should be a string to be sent to the child process, or None, if no data should be sent to the child.

communicate() returns a tuple (stdout, stderr).

Note: The data read is buffered in memory, so do not use this method if the data size is large or unlimited.

如果用subprocess模块实现第一节的功能,代码如下:

cmd = ['ping','baidu.com']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
p.stdout.read().decode('gbk')

输出:

'\r\n正在 Ping baidu.com [123.125.115.110] 具有 32 字节的数据:\r\n来自 123.125.115.110 的回复: 字节=32 时间=50ms TTL=44\r\n来自 123.125.115.110 的回复: 字节=32 时间=51ms TTL=44\r\n来自 123.125.115.110 的回复: 字节=32 时间=50ms TTL=44\r\n来自 123.125.115.110 的回复: 字节=32 时间=51ms TTL=44\r\n\r\n123.125.115.110 的 Ping 统计信息:\r\n    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),\r\n往返行程的估计时间(以毫秒为单位):\r\n    最短 = 50ms,最长 = 51ms,平均 = 50ms\r\n'

subprocess输出的转码问题

在上面的示例代码中,我们注意到,代码最后一行使用了GBK格式解码。我们是怎样确定解码的格式的呢?

参考 python使用subprocess获取命令行输入后中文转码问题

subprocess的输出格式与命令行的输出格式一致,而命令行的输出格式可以按照如下方式查询:

在命令行执行chcp指令,得到活动页代码。比如,在我的电脑中执行结果如下所示。

C:\Users\Administrator>chcp
活动代码页: 936

然后依照下表查询可得字符集编码。

MS-DOS为以下国家和语言提供字符集:
  代码页描述
  1258 越南语
  1257 波罗的语
  1256 阿拉伯语
  1255 希伯来语
  1254 土耳其语
  1253 希腊语
  1252 拉丁 1 字符 (ANSI)
  1251 西里尔语
  1250 中欧语言
  950 繁体中文
  949 朝鲜语
  936 简体中文(默认) GBK
  932 日语
  874 泰国语
  850 多语种 (MS-DOS Latin1)
  437 MS-DOS 美国英语
  65001 UTF-8

你可能感兴趣的:(Python | 用Python获取Windows控制台输出)