代码之家  ›  专栏  ›  技术社区  ›  tedtoal

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

  •  20
  • tedtoal  · 技术社区  · 9 年前

    在snakemake中,建议使用shell()函数执行多个命令的方法是什么?

    2 回复  |  直到 9 年前
        1
  •  51
  •   tomkinsc    9 年前

    你可以打电话 shell() run run: shell: ):

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

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

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

    shell 块,并像在shell脚本中一样编写命令。这可以说是纯shell规则中可读性最强的规则:

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

    || 和 && :

    rule processing_step:
        input:
            # [...]
        output:
            # [...]
        shell:
            "command_one && echo 'command_one worked' || echo 'command_one failed'"
    
        2
  •  4
  •   Michael Hall    6 年前

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

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

    scripts/run_somecommand.sh 这将执行以下操作:

    #!/usr/bin/env sh
    input=$(realpath $1)
    output=$(realpath $2)
    log=$(realpath $3)
    sample="$4"
    
    mkdir -p data/analysis/${sample}
    cd data/analysis/${sample}
    somecommand --input ${input} --output ${output} 2> ${log}
    

    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