使用 shell() 执行多个 shell 命令的推荐方法

Recommended way to do multiple shell commands with shell()

在snakemake中,推荐使用shell()函数执行多条命令的方式是什么?

您可以在规则的 run 块内多次调用 shell()(规则可以指定 run: 而不是 shell:):

rule processing_step:
    input:
        # [...]
    output:
        # [...]
    run:
        shell("somecommand {input} > tempfile")
        shell("othercommand tempfile {output}")

否则,由于 运行 块接受 Python 代码,您可以将命令列表构建为字符串并迭代它们:

rule processing_step:
    input:
        # [...]
    output:
        # [...]
    run:
        commands = [
            "somecommand {input} > tempfile",
            "othercommand tempfile {output}"
        ]
        for c in commands:
            shell(c)

如果您在执行规则期间不需要 Python 代码,您可以在 shell 块中使用三引号字符串,并像在 [= =32=]脚本。对于纯 shell 规则,这可以说是最具可读性的:

rule processing_step:
    input:
        # [...]
    output:
        # [...]
    shell:
        """
        somecommand {input} > tempfile
        othercommand tempfile {output}
        """

如果 shell 命令依赖于前面命令的 success/failure,它们可以与通常的 shell 脚本运算符连接,例如 ||&&:

rule processing_step:
    input:
        # [...]
    output:
        # [...]
    shell:
        "command_one && echo 'command_one worked' || echo 'command_one failed'"

以为我会抛出这个例子。这可能不是对用户问题的直接回答,但我在搜索类似内容并试图弄清楚如何 运行 多个 shell 命令和 运行 一些命令时遇到了这个问题它们在特定目录中(出于各种原因)。

为了保持整洁,您可以使用 shell 脚本。

假设我有一个 shell 脚本 scripts/run_somecommand.sh 执行以下操作:

#!/usr/bin/env sh
input=$(realpath )
output=$(realpath )
log=$(realpath )
sample=""

mkdir -p data/analysis/${sample}
cd data/analysis/${sample}
somecommand --input ${input} --output ${output} 2> ${log}

然后在你的 Snakemake 规则中你可以这样做

rule somerule:
    input:
        "data/{sample}.fastq"
    output:
        "data/analysis/{sample}/{sample}_somecommand.json"
    log:
        "logs/somecommand_{sample}.log"
    shell:
        "scripts/run_somecommand.sh {input} {output} {log} {sample}"

注意:如果您正在使用 Mac 而没有 realpath,您可以使用 brew install coreutils 安装,这是一个非常方便的命令。