第一个Snakemake工作流:单规则Hello World,理解Snakefile结构

我们正式开始写Snakemake。 你先别紧张,第一个例子连生物信息学数据都不用——就一个“Hello World”。 说白了,就是让你看看Snakefile长什么样,怎么跑起来。

1. 一条规则就是一条生产线

我个人习惯把Snakemake里的rule想象成一个小型加工厂:

  • input → 原材料(源文件)
  • output → 成品(目标文件)
  • shell → 加工机器(你执行的那条命令)

整个工作流就是多个这样的工厂串起来。我们先只建一个。

新建一个空白文件夹,在里面创建文件 Snakefile(注意首字母大写),写入以下内容:

# 我的第一个Snakemake规则
rule hello:
    input:
        "data/input.txt"
    output:
        "results/output.txt"
    shell:
        "cp {input} {output}"

然后在同一目录下创建 data/input.txt,随便写点内容,比如 Hello Snakemake!。 打开终端,执行:

snakemake -j1

你会看到Snakemake自动创建了 results 文件夹,并把文件复制过去了。 检查一下 results/output.txt,应该和输入内容一样。恭喜,你的第一个工作流跑通了。

提示:Snakemake默认只创建输出文件所在的目录(这里就是 results/),不会创建其他额外目录。如果你需要更复杂的目录结构,记得用 shell: 里的 mkdir -p 处理。

2. Snakefile结构拆解

刚才那几行代码,其实已经把Snakefile的核心骨架都暴露给你了。咱们拆开看:

元素 说明 我踩过的坑
rule 定义规则的保留字,后面跟规则名称(如 hello),冒号结尾 名称别用空格、别用 -,用下划线 _ 最安全
input: 列出所有输入文件,可以写多个,每行一个 路径是相对于Snakefile所在目录的,不是相对于规则目录
output: 列出所有输出文件,Snakemake用它们来判断规则是否需要执行 输出文件必须是一个或多个具体路径,不能用通配符(初学先别碰通配符)
shell: 要执行的shell命令,用 {input} 和 {output} 引用文件 我当时写错成 $input,运行报错找了一小时

缩进在Snakemake里极其重要。我记得有一次同事把一个空格缩进和Tab混在一起,Snakemake直接报 SyntaxError。 我建议你:

  • 统一用4个空格缩进,别用Tab。
  • 编辑器里开启“显示空白字符”,一眼就能看出问题。
警告:Snakefile是Python语法扩展,所以它要求严格的缩进一致性。如果你不小心用了Tab,Python解释器会报 TabError。我曾经帮人调试过一个80行的Snakefile,最后发现是第三行的Tab混进去了——整整浪费了半天。

3. 快速验证你的工作流(别急着跑)

我刚开始用Snakemake时,每次改完规则就 snakemake -j4 直接跑,结果常常因为路径写错而把原文件覆盖了。 后来我养成了一个习惯——先干跑:

snakemake -n

这个 -n (dry-run)会打印出每条规则要执行什么命令,但不会真的执行。 你还可以加上 -p 显示完整命令:

snakemake -n -p

输出类似:

Building DAG of jobs...
Job stats:
job      count    min threads    max threads
hello         1              1              1
...
[Mon Oct 14 10:00:00 2025]
rule hello:
    input: data/input.txt
    output: results/output.txt
    jobid: 0
    cp data/input.txt results/output.txt

看到最后那行 cp data/input.txt results/output.txt 就是你马上要执行的命令。确认无误后再去掉 -n 运行。

记住这条黄金法则:任何工作流改动后,先 snakemake -n -p 预览,再动真格。这是避免“误删全基因组数据”的最后一道防线。

4. 一张图看懂Snakefile结构

下面这张图帮你把刚才讲的知识点串起来:一条规则就是一个带输入/输出/命令的加工单元,Snakemake根据输出是否存在决定要不要运行,并通过shell:里的占位符把路径传进去。

Snakefile 单规则结构 input: data/input.txt rule hello: input: ... output: ... shell: ... output: results/output.txt shell: "cp {input} {output}" → 实际执行:cp data/input.txt results/output.txt 路径传递 路径传递 先 dry-run 预览:snakemake -n -p 确认后执行:snakemake -j1

5. 小结——你已经入门了

到现在为止,你掌握了:

  • Snakefile的基本结构:rule + input + output + shell
  • 如何运行一条规则:snakemake -j1
  • 安全预览命令:snakemake -n -p
  • 缩进的重要性(别再踩我踩过的坑了)

下个阶段我们会进入真正的生物信息学场景——处理多个样本、使用通配符。但别急,先把Hello World玩熟。 记得每次改完Snakefile都先-n预览再跑,这是最保命的习惯。