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

通过Python Subprocess运行Shell脚本时ANSI转义码异常问题

Perl脚本命令行参数混入ANSI转义码导致文件无法打开(Subprocess运行异常)

问题背景

用Python的subprocess模块构建生物信息学流水线(调用.sh脚本实现并行计算),6个月前运行正常,现在出现异常:部分Perl脚本的命令行参数被插入[35m这类ANSI转义码,导致文件路径无效无法打开。直接在zsh终端运行完全相同的.sh脚本无问题,尝试多种subprocess启动方式均未解决。


错误日志(Subprocess运行)

2024-06-27 13:16:29 /Users/kevin/VirVarSeq/map_vs_consensus.pl  !---- Paired end mapping using [35m./Sample_Q23.17-NHG_3BNC-10_E8-240314/Q23.17-NHG_3BNC-10_E8-240314_R1.fastq.gz[m[m [35m./Sample_Q23.17-NHG_3BNC-10_E8-240314/Q23.17-NHG_3BNC-10_E8-240314_R2.fastq.gz[m[m ...
[M::bwa_idx_load_from_disk] read 0 ALT contigs
[E::main_mem] fail to open file `[35m./Sample_Q23.17-NHG_3BNC-10_E8-240314/Q23.17-NHG_3BNC-10_E8-240314_R1.fastq.gz[m[m'.

正常日志(终端运行)

2024-06-27 13:08:04 /Users/kevin/VirVarSeq/map_vs_consensus.pl  !---- Paired end mapping using ./Sample_Q23.17-NHG_3BNC-10_E8-240314/Q23.17-NHG_3BNC-10_E8-240314_R1.fastq.gz ./Sample_Q23.17-NHG_3BNC-10_E8-240314/Q23.17-NHG_3BNC-10_E8-240314_R2.fastq.gz ...
[M::bwa_idx_load_from_disk] read 0 ALT contigs
[M::process] read 41262 sequences (6098025 bp)...

出错前的.sh脚本内容

#!/bin/zsh
#VirVarSeq Pipeline

seq_header=Q23.17-NHG_3BNC-10_E8-240314
ln -s /Users/kevin/VirVarSeq/R ./
mkdir Sample_$seq_header
ln -s $PWD/*fastq.gz ./Sample_$seq_header
echo $seq_header > samples.txt

#make directories as VirVar would have:
mkdir VirVarResults
mkdir VirVarResults/codon_table
mkdir VirVarResults/consensus
mkdir VirVarResults/map_vs_consensus
mkdir VirVarResults/map_vs_ref
mkdir VirVarResults/mixture_model

#use bam file from lofreq mapping (unfortunately need it in SAM format):
samtools view -h -o ./VirVarResults/map_vs_ref/$seq_header.sam $seq_header.bam "Q23.17-NHG"

indir=.
outdir=./VirVarResults
samples=./samples.txt
ref=/Users/kevin/Documents/Bienasz_Lab/HIV1_bNab_Env_Escape/Sequencing_analysis/Variant_calling/3BNC117/240621_MiSeqRun/Reference_Genomes/Q23.17-NHG.fasta
startpos=6170
endpos=8829
region_start=6221
region_len=853
qv=0

consensus.pl --samplelist $samples --ref $ref --indir $indir --outdir $outdir --start $startpos --end $endpos >> VirVarSeq.log 2>&1

原因分析

ANSI转义码用于终端彩色输出,出现此问题的核心原因是:

  • 近期更新的Perl脚本、bwa或samtools等工具默认开启了彩色输出
  • Subprocess运行时的环境变量(如TERM、COLORTERM)与zsh终端不一致,工具误判为支持彩色输出,导致转义码被混入命令行参数而非仅用于日志渲染
  • Perl脚本中引入的彩色输出逻辑未判断运行环境是否为交互式终端

解决方案

1. 在.sh脚本中禁用彩色输出

在脚本开头添加环境变量,强制所有工具关闭彩色输出:

#!/bin/zsh
# 禁用彩色输出
export TERM=dumb
export COLORTERM=
export BWA_COLOR=0
export SAMTOOLS_COLOR=0

# 原脚本内容...

2. 修改Python Subprocess的运行环境

调用subprocess时显式设置非交互式终端环境:

import subprocess
import os

# 复制当前环境并修改关键变量
env = os.environ.copy()
env["TERM"] = "dumb"
env.pop("COLORTERM", None)

# 调用.sh脚本
subprocess.run(["zsh", "your_pipeline.sh"], env=env, check=True)

3. 修正Perl脚本的彩色输出逻辑

如果是Perl脚本本身输出转义码到参数,找到彩色输出的代码块,添加终端判断:

use Term::ANSIColor qw(:constants);
# 仅当输出到交互式终端时启用颜色
my $enable_color = -t STDOUT;

# 输出文件路径时判断
if ($enable_color) {
    print MAGENTA . $file_path . RESET;
} else {
    print $file_path;
}

4. 临时清理路径中的转义码

若无法修改工具或脚本,可在.sh脚本中添加路径清理函数:

# 清理字符串中的ANSI转义码
clean_ansi() {
    echo "$1" | sed -e 's/\x1b\[[0-9;]*m//g'
}

# 调用Perl脚本时使用清理后的参数
consensus.pl --samplelist $(clean_ansi $samples) --ref $(clean_ansi $ref) \
--indir $(clean_ansi $indir) --outdir $(clean_ansi $outdir) \
--start $startpos --end $endpos >> VirVarSeq.log 2>&1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:10:13