【问题标题】:how to write a bash script that creates new scripts iteratively如何编写一个迭代地创建新脚本的 bash 脚本
【发布时间】:2026-01-29 20:55:01
【问题描述】:

如何编写一个循环遍历所有主题并为每个主题创建一个新脚本的脚本?目标是创建一个脚本,在超级计算机上为每个主题运行一个名为 FreeSurfer 的程序。超级计算机队列限制了每个脚本/作业需要多长时间,所以我会让每个作业运行 1 个主题。最终我想自动化作业提交过程,因为我不能同时提交所有作业。在我的主题文件夹中,我有三个主题:3123、3315 和 3412。

我熟悉 MATLAB 脚本,所以我想像这样

for i=1:length(subjects)
    nano subjects(i).sh
        <contents of FreeSurfer script>
        input: /subjects(i)/scan_name.nii
        output: /output/subjects(i)/<FreeSurfer output folders>
end

我知道我混合了 MATLAB 和 linux 的各个方面,但希望相对清楚目标是什么。如果有更好的方法,请告诉我。

这是给定主题的 FreeSurfer 脚本示例

#!/bin/bash
#PBS -l walltime=25:00:00
#PBS -q long

export FREESURFER_HOME=/gpfs/software/freesurfer/6.0.0/freesurfer
source $FREESURFER_HOME/SetUpFreeSurfer.sh

export SUBJECTS_DIR=/gpfs/projects/Group/ppmi/freesurfer/subjects/

recon-all -i /gpfs/projects/Group/ppmi/all_anat/3105/Baseline/*.nii -s 
$SUBJECTS_DIR/freesurfer/subjects/3105 -autorecon-all

-i 选项提供输入,-s 选项提供输出。

【问题讨论】:

  • “主题”是什么意思?你能举个例子来说明你正在尝试做什么(手动过程)吗?然后我们可以尝试自动化它。
  • @melpomene 我用示例脚本更新了问题
  • 这听起来像XY problem。与其动态创建脚本,不如运行具有不同参数的相同脚本?
  • 您是什么意思, 示例脚本?这不是关于多个脚本吗?而且你还没有解释什么是主题。
  • 为什么不直接将主题编号作为脚本的参数,而不必为每个主题创建单独的脚本?

标签: bash


【解决方案1】:

更改您的脚本以接受 主题 作为参数,这样您就只有一个通用脚本。

#!/bin/bash
#PBS -l walltime=25:00:00
#PBS -q long

subject="$1"

export FREESURFER_HOME=/gpfs/software/freesurfer/6.0.0/freesurfer
source $FREESURFER_HOME/SetUpFreeSurfer.sh

export SUBJECTS_DIR=/gpfs/projects/Group/ppmi/freesurfer/subjects/

recon-all -i /gpfs/projects/Group/ppmi/all_anat/"$subject"/Baseline/*.nii -s 
$SUBJECTS_DIR/freesurfer/subjects/"$subject" -autorecon-all

你可以为你的所有科目调用它

for s in 3123 3315 3412; 
do
   ./yourscriptnamehere.sh "$s"
done

根据需要添加错误处理。

【讨论】:

  • 我相信#PBS cmets 是对作业调度程序的指令——OP 的问题可能是他们不知道如何通过该调度程序传递参数。
  • 我认为它们只传递输入/输出目录,不确定调度程序值是否也需要参数化。
  • 我同意调度器的值不需要参数化,但重点是目录名可能需要通过qsub传递,其实不是显然,OP 知道这是可能的或如何做到这一点。 parameter for shell scripts that is started with qsub 可能是相关的。