subprocess.__init__编码问题
subprocess.__init__
函数是 Python 的 subprocess
模块中的一部分,它用于创建进程对象。当处理来自其他程序的输出时,可能会遇到编码问题,特别是当你从标准输入、标准输出或错误流(stdin, stdout, stderr)读取内容时。
如果输出不是默认的 ASCII 编码,比如 UTF-8,而是使用了本地系统或其他非标准编码,如果没有正确的设置,就可能导致乱码。例如,如果你在 Windows 系统上运行一个使用非 UTF-8 编码的日文命令,而直接读取其输出,可能会看到一堆无法识别的字符。
解决这个问题通常需要指定输出流的编码。可以使用 universal_newlines=True
参数打开文件描述符,这会自动将换行符标准化并尝试根据文本数据的 BOM 或前缀猜测编码。另外,也可以显式地设置 encoding
参数,如:
p = subprocess.Popen(command, stdout=subprocess.PIPE, encoding='utf-8')
output, error = p.communicate()
这样,所有的输出都将被视为 Unicode 字符串,减少了编码问题。但是,如果不确定确切的编码,可能需要手动解析或使用第三方库如 chardet
来检测编码。
class RunSubprocess(Operation): """ Run a command in subprocess. Important Reminder: This is only recommended for calling service-specific command line tools, such as mclagdctl, "docker exec", mstpctl, etc., where no other alternative is available. Using this with "show" and "config" command will result in MAJOR PERFORMANCE DEGRADATION and cancel any benefit of the new klish python plugin. """ def __init__(self, cmd): """ :param cmd: a list of command line params to run. For example: ["mclagdctl", "dump", "state"] """ self._cmd = cmd def __call__(self, data): data = six.text_type(data) proc = subprocess.Popen( self._cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE ) return proc.communicate(data.encode())[0].decode() 请解释这段代码,逐字逐句
这段代码定义了一个名为 RunSubprocess
的类,它是一个操作(Operation
)的子类。该类用于在子进程中运行命令。
代码中的 RunSubprocess
类具有以下特点:
类的注释提醒用户只推荐用于调用特定服务的命令行工具,如
mclagdctl
、docker exec
、mstpctl
等,其中没有其他可替代的选项。使用该类执行 "show" 和 "config" 命令将导致性能严重降低,并取消使用新的 klish Python 插件的任何好处。__init__
方法接受一个参数cmd
,它是一个包含要运行的命令行参数的列表。例如:["mclagdctl", "dump", "state"]
。__call__
方法是类的实际执行逻辑。它接受一个参数data
,并将其转换为字符串类型。然后,通过调用subprocess.Popen
创建一个子进程,并将命令行参数传递给子进程。最后,使用communicate
方法与子进程进行交互,将输入数据编码后发送到子进程的标准输入,并获取子进程的标准输出结果。最终,返回解码后的标准输出结果。
总的来说,该类提供了一个方便的接口来在子进程中运行命令,并获取命令的输出结果。但需要注意的是,根据类的注释建议,仅推荐用于特定的命令行工具,并警告不推荐用于 "show" 和 "config" 命令,以避免性能下降。
import os import subprocess class ControlLd: def __init__(self,path): os.putenv('Path',path) print(os.putenv('Path',path)) def run_command(self,command): """运行cmd命令""" pipe=subprocess.Popen(args=command,stdout=subprocess.PIPE,shell=True,encoding='gbk') pipe=pipe.stdout.read() return pipe
这是一个 Python 类 ControlLd,它的作用是运行 cmd 命令。它有两个方法:
__init__(self, path)
方法:初始化类,并将系统环境变量 Path 设置为 path。run_command(self, command)
方法:运行 cmd 命令,返回命令输出。
在 run_command()
方法中,首先使用 subprocess.Popen()
函数创建一个子进程,执行传入的命令。stdout=subprocess.PIPE
表示将子进程的输出重定向到一个管道中,shell=True
表示在命令行中执行命令。使用 encoding='gbk'
将输出编码设置为 GBK,以便在 Windows 系统上正确显示中文字符。
最后,使用 stdout.read()
方法读取管道中的输出,并将其返回。
相关推荐
















