我正在使用 awk 脚本来处理文本文件,当遇到某个字符串时,它会退出。
{
if ($1 ~ /^>/){
if (($1 ~ /.{5}.+/) || ($1 ~ /^>MT/)) {
exit
} else {
print ">chr"substr($1,2)"_"genome, $3, $4, $5
}
} else {
print
}
}
该脚本工作得很好,并且在从终端运行它时执行了我想要的操作(使用我的 Snakemake micromamba env,所以应该是相同的 awk 版本),但是当我使用 Snakemake 运行它时,我收到以下消息:
Error in rule filter_raw_genome:
jobid: 2
input: DATA/GENOMES/RAW/homo_sapiens/GRCh38.fa.gz
output: DATA/GENOMES/RAW/homo_sapiens/GRCh38.fa
log: snakemake_logs/filter_raw_genome/homo_sapiens_GRCh38.log (check log file(s) for error details)
shell:
gunzip -c DATA/GENOMES/RAW/homo_sapiens/GRCh38.fa.gz | awk -f SCRIPTS/chrom_filer_spike.awk -v genome=GRCh38 > DATA/GENOMES/RAW/homo_sapiens/GRCh38.fa
(one of the commands exited with non-zero exit code; note that snakemake uses bash strict mode!)
GNU awk 手册 指出“如果提供了退出参数,则其值将用作 awk 进程的退出状态代码。如果未提供参数,退出将导致 awk 返回“成功”状态。”,所以我不确定snakemake读取的错误代码来自哪里。
有没有办法让 awk 尽早中断其处理循环而不生成错误代码?
编辑:日志文件为空。如果有一种方法可以使脚本更加明确并检查这是否确实导致其失败,我可以尝试一下。
这已在上面的评论中得到回答,但我将进行总结,以便稍后阅读本文的人受益。
该错误最常见于如下命令:
gunzip -c {input} | head -n 4
在这种情况下,自定义
awk
脚本将扮演 head
的角色,但效果是相同的。由于管道中的第二个命令不会消耗 {input}
中的所有行,因此 gunzip
命令可能会以非零状态退出(特别是代码 141,因为 shell 强制关闭管道)。通常这没有任何效果,但是,正如 Snakemake 错误所示,“snakemake uses bash strict mode!
”。
“Bash 严格模式”是
-euo pipefail
。也就是说,管道内命令的任何非零退出都将是错误,并且(由于 -e)该错误将立即导致失败。令人烦恼的是,没有错误消息,Snakemake 也没有报告脚本退出状态(即 141),所以问题并不明显。
有几种可能的修复方法:
exit
(gunzip -c {input} || true) | head -n 4
pipefail
来禁用此 shell 代码的
set +o pipefail ;
在这种情况下,最终的答案是最简洁的。如果输入文件已损坏,它可能会掩盖
gzip
中的错误,但这可以很容易地检查。
其他评论表明这个特定的 awk 脚本可能存在进一步的问题,但以上是作者确认的原始问题的答案。