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

在Snakemake中执行shell脚本无法识别input等内置变量怎么办

问题根因

Snakemake 仅会对 Snakefile 规则中 shell 字段内直接编写的内容做 {input}/{output}/{params} 占位符的渲染替换,你调用的外部独立 shell 脚本不会被 Snakemake 解析,因此脚本内的占位符会被当做普通字符串原样执行,才会出现找不到路径的报错。

可行解决方案
  • 方法一:通过位置参数传递变量(最常用,适配性最高)
    首先修改 Snakefile 的 shell 字段,把需要的变量按顺序传给脚本:
rule xxx:
    input:
        munged = 'results/munged.sumstats.gz'
    output:
        ldsc = 'results/ldsc.txt'
    params:
        mkdir = 'results/ldsc_results/',
        ldsc_sumstats = '/resources/ldsc_sumstats/',
    shell:
        # 按顺序传递所有需要用到的变量给shell脚本
        "scripts/run_gc.sh {input.munged} {params.mkdir} {params.ldsc_sumstats} {output.ldsc}"

再修改scripts/run_gc.sh,用 shell 的位置参数读取传入的值即可:

#!/bin/bash
# $1对应第一个传入参数:input.munged
# $2对应第二个传入参数:params.mkdir
# $3对应第三个传入参数:params.ldsc_sumstats
# $4对应第四个传入参数:output.ldsc

chmod 770 "$1"
mkdir -p "$2"

ldsc=$(ls "$3")
for i in $ldsc; do
# 后续用到output的场景直接用$4即可
...

调用前可以给脚本加可执行权限,或者在shell调用时增加bash前缀,比如bash scripts/run_gc.sh ...避免执行报错。

  • 方法二:通过环境变量传递(适合参数多的场景,避免位置参数顺序错乱)
    可以在规则中用env字段定义需要传递的环境变量,Snakemake会自动把这些变量传入shell运行环境:
rule xxx:
    input:
        munged = 'results/munged.sumstats.gz'
    output:
        ldsc = 'results/ldsc.txt'
    params:
        mkdir = 'results/ldsc_results/',
        ldsc_sumstats = '/resources/ldsc_sumstats/',
    # 定义要传入shell的环境变量
    env:
        INPUT_MUNGED = lambda wildcards, input: input.munged,
        PARAMS_MKDIR = lambda wildcards, params: params.mkdir,
        PARAMS_LDSC_SUMSTATS = lambda wildcards, params: params.ldsc_sumstats,
        OUTPUT_LDSC = lambda wildcards, output: output.ldsc
    shell:
        "scripts/run_gc.sh"

之后修改scripts/run_gc.sh直接读取对应的环境变量即可:

#!/bin/bash
chmod 770 "$INPUT_MUNGED"
mkdir -p "$PARAMS_MKDIR"

ldsc=$(ls "$PARAMS_LDSC_SUMSTATS")
for i in $ldsc; do
...
  • 方法三:直接把shell逻辑写在Snakefile的shell块中(适合短脚本)
    如果你的shell脚本逻辑不复杂,可以直接把所有命令放到shell字段里,就能直接用Snakemake的占位符:
rule xxx:
    input:
        munged = 'results/munged.sumstats.gz'
    output:
        ldsc = 'results/ldsc.txt'
    params:
        mkdir = 'results/ldsc_results/',
        ldsc_sumstats = '/resources/ldsc_sumstats/',
    shell:
        """
        chmod 770 {input.munged}
        mkdir -p {params.mkdir}

        ldsc=$(ls {params.ldsc_sumstats})
        for i in $ldsc; do
        ...
        """

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:18:04