处理snakemake中的SIGPIPE错误

5
以下是一段 Snakemake 脚本:
rule all:
    input:
        'test.done'

rule pipe:
   output:
       'test.done'
   shell:
        """
        seq 1 10000 | head > test.done
        """

出现以下错误:

snakemake -s test.snake

Provided cores: 1
Rules claiming more threads will be scaled down.
Job counts:
    count   jobs
    1   all
    1   pipe
    2

rule pipe:
    output: test.done
    jobid: 1

Error in job pipe while creating output file test.done.
RuleException:
CalledProcessError in line 9 of /Users/db291g/Tritume/test.snake:
Command '
        seq 1 10000 | head > test.done
        ' returned non-zero exit status 141.
  File "/Users/db291g/Tritume/test.snake", line 9, in __rule_pipe
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/thread.py", line 55, in run
Removing output files of failed job pipe since they might be corrupted:
test.done
Will exit after finishing currently running jobs.
Exiting because a job execution failed. Look above for error message

这里的解释返回非零退出状态141似乎表明,snakemake已经捕获了由head发送的SIGPIPE故障。我认为严格地说,snakemake在捕获故障方面做得很对,但我想知道是否有可能忽略一些类似于这种错误的类型。我有一个使用head命令的snakemake脚本,我正在尝试找到一种解决这个错误的方法。


1
是的,Snakemake默认设置了pipefail,因为在大多数情况下人们会隐含地期望这样。您可以通过在shell命令前面添加set +o pipefail;来针对特定命令取消激活它。 - Johannes Köster
谢谢!如果您将此作为答案发布,我会接受它。 - dariober
2个回答

7

是的,Snakemake默认设置pipefail,因为在大多数情况下,这是人们隐含期望的。您可以通过在shell命令前添加 set +o pipefail; 来针对特定命令取消激活它。


谢谢。也许需要提醒一下,set +o pipefail 应该小心使用,因为它将使得类似于以下这样的错误命令也会成功:seq 1 10000 | FooBar | head > {output} - dariober
确切地说,这就是为什么Snakemake默认启用pipefail的原因。 - Johannes Köster
1
我只是使用替代命令 awk 'NR<=10'sed -n '1,10p' 代替 head 命令,以避免 @dariober 提到的问题。 - Manavalan Gajapathy

3
一种有点笨重的解决方案是在脚本后面添加|| true。这样会使命令始终正常退出,这是不可接受的。要检查脚本是否成功,可以查询数组变量${PIPESTATUS[@]}以确保它包含预期的退出码:

以下脚本是可以的:

seq 1 10000 | head | grep 1 > test.done || true
echo ${PIPESTATUS[@]}
141 0 0

这是不可以的:

seq 1 10000 | head | FOOBAR > test.done || true
echo ${PIPESTATUS[@]}
0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接