如何在Python中为subprocess.run格式化复杂长bash命令?
解决Python执行复杂Bash命令的转义问题
第一条命令修正
原命令的核心问题是Python字符串对\t、\n的转义解析,以及单双引号的嵌套冲突。可以通过三重双引号包裹命令字符串,同时对转义字符做二次转义,确保Bash能正确识别制表符和换行符:
import subprocess # 第一条命令:生成格式化表头并写入日志 cmd_header = """top -n1 -b | awk -vtime="$(date +%Y-%m-%d-%T)" 'NR==7{printf("Time\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\n",$1,$5,$6,$9,$10,$11,$NF)}' > ~/logs/perfmon.log""" # 执行命令(同步等待完成) subprocess.run(cmd_header, shell=True, check=True)
- 三重双引号
"""允许字符串内部直接使用单引号和双引号,无需额外转义 - 将原命令中的
\t改为\\t、\n改为\\n,确保Bash接收到的是字面意义的转义字符,而非Python解析后的制表符/换行符 check=True会在命令执行失败时抛出异常,方便排查问题
第二条命令实现(后台持续记录)
要实现不等待Bash命令完成,需用subprocess.Popen而非subprocess.run,同时通过Bash的&将进程放入后台,再配合Python的输出重定向避免阻塞:
import subprocess def start_process_monitor(process_name): # 第二条命令:持续记录指定进程的性能数据 cmd_monitor = f"""top -b -d 1 -p $(pgrep {process_name}) >> ~/logs/perfmon.log &""" # 启动后台进程,不等待执行完成 subprocess.Popen( cmd_monitor, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True # 确保进程不受Python退出影响 ) # 调用示例 start_process_monitor("your_target_process")
top -b以批处理模式运行,适合重定向输出;-d 1设置刷新间隔为1秒$(pgrep {process_name})自动获取目标进程的PID,若有多个同名进程,top会同时监控所有匹配项>>以追加模式写入日志,避免覆盖表头&将top进程放入Bash后台,配合Popen实现Python不等待start_new_session=True确保即使Python退出,监控进程仍能继续运行stdout和stderr重定向到DEVNULL避免Python捕获冗余输出
内容的提问来源于stack exchange,提问作者rainbringer
相关产品推荐
相关产品推荐

