You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3中用subprocess执行含特殊字符子命令的Pythonic方法

问题描述

我需要在Python脚本中执行这条终端能正常运行的shell命令:

pd schedule:list -j | egrep '\"(name|time_zone)\b.*$$' | awk '/name/ {print $0} /time_zone/ {print $0 "\n"}' >> schedules.txt

这条命令的执行步骤如下:

  • 以JSON格式输出大型列表:
    pd schedule:list -j
    
  • 通过egrep过滤出包含"name"和"time_zone"的行:
    | egrep '\"(name|time_zone)\b.*$$'
    
  • 通过awk将每两行(一组name和time_zone)分组,每组后加空行:
    | awk '/name/ {print $0} /time_zone/ {print $0 "\n"}'
    
  • 将结果追加到schedules.txt文件:
    >> schedules.txt
    

终端执行后的结果示例:

"name": "1st Line 7-17",
    "time_zone": "Europe/Helsinki",

    "name": "24-5",
    "time_zone": "Europe/Warsaw",

    "name": "Amazon Connect Test",
    "time_zone": "Europe/Warsaw",
    
     ... etc

但因为命令里有大量特殊字符,用Python 3的subprocess模块执行时遇到了困难,请问最简洁的Pythonic实现方式是什么?

解决方案

方式一:直接通过subprocess执行完整shell命令(处理特殊字符)

如果一定要复用原shell逻辑,用原始字符串包裹命令并指定shell=True即可避免转义问题:

import subprocess

cmd = r'''pd schedule:list -j | egrep '\"(name|time_zone)\b.*$$' | awk '/name/ {print $0} /time_zone/ {print $0 "\n"}' >> schedules.txt'''
subprocess.run(cmd, shell=True, check=True)

注:check=True会在命令执行失败时抛出异常,方便排查问题;原始字符串r''可避免Python对转义字符的额外处理。

方式二:用Python原生处理JSON(更Pythonic,推荐)

原命令核心是解析JSON并提取指定字段,直接用Python的json模块处理更可靠,无需依赖外部shell工具,也规避了特殊字符的麻烦:

import json
import subprocess

# 执行命令获取JSON输出
result = subprocess.run(['pd', 'schedule:list', '-j'], capture_output=True, text=True, check=True)
schedules = json.loads(result.stdout)

# 提取字段并写入文件
with open('schedules.txt', 'a', encoding='utf-8') as f:
    for item in schedules:
        f.write(f'    "name": "{item["name"]}",\n')
        f.write(f'    "time_zone": "{item["time_zone"]}",\n\n')

注:

  • 用列表形式传参(无需shell=True)更安全,不存在shell注入风险
  • 直接解析JSON后提取字段,格式可灵活自定义,比shell过滤更可控
  • capture_output=True捕获命令输出,text=True让输出以字符串形式返回,便于解析

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 23:30:50