Apptainer挂载多目录运行souporcell脚本报错求助
Apptainer运行souporcell多目录文件访问问题解决方案
问题背景
使用Apptainer(兼容Singularity 3.9.2)结合bash脚本批量运行souporcell软件,需读取分散在不同目录的.bam、.tsv、.fa、.vcf文件。单目录测试时,通过--bind将外部路径挂载到容器内/tmp可正常运行,但批量处理数千样本子目录时,脚本出现FileNotFoundError,提示容器内路径对应文件不存在,确认是容器挂载机制导致。
测试成功的单目录命令
apptainer exec --bind /mypath/souporcell:/tmp souporcell_latest.sif souporcell_pipeline.py -i /tmp/A.merged.bam -b /tmp/GSM2560245_barcodes.tsv -f /tmp/refdata-cellranger-GRCh38-3.0.0/fasta/genome.fa -t 16 -o /tmp -k 3
问题脚本(路径:/mypath/scripts/souporcell_skipRemap_k_3.sh)
#!/bin/bash module load apptainer/1.1.4 SOUPORCELL_DIR=/mypath/data/test/souporcell BATCH=${1} SAMPLE=$(echo "$BATCH" | cut -d"_" -f1) BAM_DIR=/mypath/data/test/fastqs/${BATCH}_OUT/outs BARCODES_DIR=/mypath/data/test/fastqs/${BATCH}_OUT/outs/filtered_feature_bc_matrix REF_DIR=/mypath/data/test/souporcell/references apptainer exec --bind $SOUPORCELL_DIR:/tmp souporcell_latest.sif souporcell_pipeline.py \ -i /tmp${BAM_DIR}/possorted_genome_bam.bam \ -b /tmp${BARCODES_DIR}/barcodes.tsv \ --fasta /tmp${REF_DIR}/refdata-gex-GRCh38-2020-A/fasta/genome.fa \ --common_variants /tmp${REF_DIR}/common_variants_grch38.vcf \ --skip_remap SKIP_REMAP \ -t 16 \ -o /tmp${SOUPORCELL_DIR}/skip_remap_OUTS/${SAMPLE}_souporcell \ -k 3
运行命令及报错信息
运行命令:
bash souporcell_skipRemap_k_3.sh B8-c2-10X_OUT
报错:
[me@server scripts]$ bash souporcell_skipRemap_k_3.sh B8-c2-10X checking modules imports done checking bam for expected tags Traceback (most recent call last): File "/opt/souporcell/souporcell_pipeline.py", line 64, in <module> with open_function(args.barcodes) as barcodes: File "/opt/souporcell/souporcell_pipeline.py", line 57, in <lambda> open_function = lambda f: gzip.open(f,"rt") if f[-3:] == ".gz" else open(f) FileNotFoundError: [Errno 2] No such file or directory: '/tmp/mypath/data/test/fastqs/B8-c2-10X_OUT/outs/filtered_feature_bc_matrix/barcodes.tsv'
问题原因
脚本中仅挂载了$SOUPORCELL_DIR到容器/tmp,但BAM_DIR、BARCODES_DIR、REF_DIR对应的外部路径并未被挂载到容器内,且错误地将这些外部路径直接拼接在/tmp后,导致容器内找不到对应的路径(容器内/tmp下并没有/mypath/...这样的子目录)。
解决方案
方案1:挂载共同父目录保持路径一致性
将所有涉及文件的共同父目录/mypath挂载到容器内的同名路径,这样容器内可以直接使用外部的绝对路径访问文件,无需修改路径格式:
#!/bin/bash module load apptainer/1.1.4 BATCH=${1} SAMPLE=$(echo "$BATCH" | cut -d"_" -f1) # 定义所有需要访问的路径 BAM_DIR=/mypath/data/test/fastqs/${BATCH}_OUT/outs BARCODES_DIR=/mypath/data/test/fastqs/${BATCH}_OUT/outs/filtered_feature_bc_matrix REF_DIR=/mypath/data/test/souporcell/references SOUPORCELL_DIR=/mypath/data/test/souporcell OUTPUT_DIR=${SOUPORCELL_DIR}/skip_remap_OUTS/${SAMPLE}_souporcell # 提前创建输出目录,避免容器内权限不足无法创建 mkdir -p ${OUTPUT_DIR} # 挂载父目录到容器,保持路径一致 apptainer exec --bind /mypath:/mypath souporcell_latest.sif souporcell_pipeline.py \ -i ${BAM_DIR}/possorted_genome_bam.bam \ -b ${BARCODES_DIR}/barcodes.tsv \ --fasta ${REF_DIR}/refdata-gex-GRCh38-2020-A/fasta/genome.fa \ --common_variants ${REF_DIR}/common_variants_grch38.vcf \ --skip_remap SKIP_REMAP \ -t 16 \ -o ${OUTPUT_DIR} \ -k 3
方案2:逐个挂载所需目录到容器指定路径
如果不想挂载大体积的父目录,可以单独挂载每个需要的目录到容器内的自定义路径,简化容器内的访问路径:
#!/bin/bash module load apptainer/1.1.4 BATCH=${1} SAMPLE=$(echo "$BATCH" | cut -d"_" -f1) # 定义外部路径 FASTQS_DIR=/mypath/data/test/fastqs/${BATCH}_OUT/outs REF_DIR=/mypath/data/test/souporcell/references SOUPORCELL_DIR=/mypath/data/test/souporcell OUTPUT_DIR=${SOUPORCELL_DIR}/skip_remap_OUTS/${SAMPLE}_souporcell mkdir -p ${OUTPUT_DIR} # 用逗号分隔多个挂载规则,将外部目录映射到容器内的短路径 apptainer exec --bind ${FASTQS_DIR}:/fastqs,${REF_DIR}:/ref,${SOUPORCELL_DIR}:/souporcell souporcell_latest.sif souporcell_pipeline.py \ -i /fastqs/possorted_genome_bam.bam \ -b /fastqs/filtered_feature_bc_matrix/barcodes.tsv \ --fasta /ref/refdata-gex-GRCh38-2020-A/fasta/genome.fa \ --common_variants /ref/common_variants_grch38.vcf \ --skip_remap SKIP_REMAP \ -t 16 \ -o /souporcell/skip_remap_OUTS/${SAMPLE}_souporcell \ -k 3
关键注意事项
- 容器内仅能访问通过
--bind挂载的外部目录,未挂载的路径无法被程序读取或写入。 - 禁止将外部绝对路径直接拼接在容器内路径后,这种操作会生成容器内不存在的嵌套路径。
- 提前在外部创建输出目录,避免容器内因权限限制无法生成新目录。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

