在Snakemake v8.10.8中使用Apptainer部署时,如何指定运行shell?
在Snakemake中为Apptainer指定容器内的Shell
问题背景
在Snakemake v8.10.8中使用docker://busybox:1.33容器编写了如下Snakefile:
rule hello_world_container: params: output_dir="results", name="standard model" output: "results/hello_world.txt" container: "docker://busybox:1.33" shell: """ mkdir -p {params.output_dir} echo "Hello my Name is {params.name}" | tee {output} """
使用以下命令运行时:
snakemake --verbose --cores 1 --printshellcmds --software-deployment-method apptainer --snakefile Snakefile hello_world_container
出现报错,原因是Apptainer默认调用bash作为容器内的shell,但busybox镜像中没有bash:
Command ' singularity exec --home '<cwd>' <cwd>/.snakemake/singularity/893d95b26cf7d03ff72563d5db3f40ca.simg bash -c 'set -euo pipefail; mkdir -p results echo "Hello my Name is standard model" | tee results/hello_world.txt'' returned non-zero exit status 255.
而直接用Apptainer指定sh运行是可行的:
$ apptainer exec docker://busybox:1.33 sh -c "echo 'hello world'" INFO: Using cached SIF image hello world
解决方案
可以通过以下几种方式为Apptainer指定容器内使用的shell:
1. 全局设置(所有规则生效)
方法1:命令行参数指定
运行Snakemake时添加--shell-executable sh参数,强制所有容器使用sh执行shell指令:
snakemake --verbose --cores 1 --printshellcmds --software-deployment-method apptainer --shell-executable sh --snakefile Snakefile hello_world_container
方法2:在Snakefile中全局配置
在Snakefile的开头添加以下代码,全局设置默认shell为sh:
shell.executable("sh") rule hello_world_container: params: output_dir="results", name="standard model" output: "results/hello_world.txt" container: "docker://busybox:1.33" shell: """ mkdir -p {params.output_dir} echo "Hello my Name is {params.name}" | tee {output} """
方法3:通过配置文件设置
在config.yaml中添加:
shell_executable: sh
然后在Snakefile开头引入配置文件:
configfile: "config.yaml" shell.executable(config["shell_executable"]) # 后续规则内容不变
2. 规则级单独设置(仅当前规则生效)
如果只想让特定规则使用sh,可以在规则内添加shell.executable("sh"):
rule hello_world_container: params: output_dir="results", name="standard model" output: "results/hello_world.txt" container: "docker://busybox:1.33" shell.executable("sh") # 仅该规则使用sh shell: """ mkdir -p {params.output_dir} echo "Hello my Name is {params.name}" | tee {output} """
3. 显式在shell指令中调用sh
直接在shell脚本里用sh -c包裹指令,这种方式无需修改Snakemake的shell配置:
rule hello_world_container: params: output_dir="results", name="standard model" output: "results/hello_world.txt" container: "docker://busybox:1.33" shell: """ sh -c 'mkdir -p {params.output_dir}; echo "Hello my Name is {params.name}" | tee {output}' """
内容的提问来源于stack exchange,提问作者Matthew Feickert
相关产品推荐
相关产品推荐

