Ubuntu环境下用Python3 subprocess提取dpkg -l输出第二列
解决Ubuntu下用Python3 subprocess提取
dpkg -l第二列的问题 刚好之前处理过类似的需求,给你捋捋解决方案——你遇到的输出混乱问题,核心是没把subprocess返回的bytes类型正确转成字符串,先搞定这个,再提取列就轻松了。
第一步:把bytes转成可读字符串
用subprocess.run()执行命令时,有两种简单的方式拿到字符串格式的输出:
- 直接加
text=True参数(Python 3.7+支持),它会自动帮你把bytes解码成字符串:
import subprocess result = subprocess.run(['dpkg', '-l'], capture_output=True, text=True) output = result.stdout
- 如果用的是更早的Python版本,那就手动用
decode('utf-8')解码:
result = subprocess.run(['dpkg', '-l'], stdout=subprocess.PIPE) output = result.stdout.decode('utf-8')
第二步:提取第二列的包名
dpkg -l的输出开头有两行是说明文本,得先跳过。然后每一行的列是用多个空格分隔的,所以不能用split(' '),得用默认的split()(它会把任意数量的空白字符当成分隔符),然后取分割后的第二个元素(索引是1,因为Python从0开始计数):
# 把输出按行拆分 lines = output.strip().split('\n') # 跳过前两行说明,遍历剩下的行 for line in lines[2:]: parts = line.split() # 有些行可能是空的或者格式异常,加个判断避免报错 if len(parts) >= 2: print(parts[1])
整合起来的完整代码
把上面的步骤整合一下,写个可复用的函数:
import subprocess def get_dpkg_package_names(): try: # 执行命令,捕获输出并自动转成字符串,check=True会在命令失败时抛异常 result = subprocess.run(['dpkg', '-l'], capture_output=True, text=True, check=True) output_lines = result.stdout.strip().split('\n') package_names = [] # 从第三行开始处理实际的包数据 for line in output_lines[2:]: parts = line.split() if parts: package_names.append(parts[1]) return package_names except subprocess.CalledProcessError as e: print(f"执行命令出错:{e.stderr}") return [] # 测试一下 if __name__ == '__main__': pkgs = get_dpkg_package_names() for pkg in pkgs: print(pkg)
几个小提醒
check=True很有用,能帮你快速发现命令执行失败的情况(不过dpkg -l一般不需要sudo权限);- 用
split()而不是指定空格分割,是因为dpkg -l的列之间可能有多个空格或者制表符,默认的split()会处理所有这些情况; - 跳过前两行是因为
dpkg -l的输出结构固定,前两行是表头说明,第三行开始才是真正的包信息。
内容的提问来源于stack exchange,提问作者Ravi OpenSource
相关产品推荐
相关产品推荐

