先上代码#!/usr/bin/perl -w use strict; use Cwd realpath; use File::Basename; use FindBin qw($Bin $Script); use Getopt::Long; use Storable; use lib /mnt/lustre/user/wubin/01.Program/Scripts/01.script/GeneLab; use Common; my $common Common - new(); $| 1; my ($group,$key,$run_type,$run, $rm_temp,$show_prerequisites,$check_before_run, $num); my rm_downstream; my $rm_self_log; my $rm_all_log; my $specific_shell; my $wait; my exclude_nodes (); #exclude_nodes (cn16, cn17); exclude_nodes (cn16); print test_0.(join , exclude_nodes).\n; GetOptions( groups \$group, keys \$key, run_types \$run_type, rm_temp! \$rm_temp, show_prerequisites! \$show_prerequisites, run! \$run, numi \$num, check_before_run! \$check_before_run, rm_downstreams \rm_downstream, rm_self_log! \$rm_self_log, rm_all_log! \$rm_all_log, specific_shells \$specific_shell, exclude_nodess \exclude_nodes, waiti \$wait ); my %PipeLine; $group genelab.q,bigmem; my $count 0; foreach my $sh(ARGV){ $count ; $PipeLine{cpu}{$sh} 2; $PipeLine{memory}{$sh} 20G; qsub_sge($sh); print test_$count.(join , exclude_nodes).\n; } #以下是正常跑流程 sub get_exclude_nodes{ my node_tmp (); foreach my $node(_) { #print test_1$node\n; if ($node !~ /\.local/) {$node . .local;} $node h!$node; push(node_tmp, $node); } my $exclude join , node_tmp; return $exclude; } sub qsub_sge{ my $sh shift; my $date date %Y-%m-%d%t%H:%M:%S;chomp($date); my $cmd qsub -cwd -V -q $group; #$group 一般是genelab.q 但也可以写成 genelab.q,bigmem,herb.q 之类的 if(scalar(exclude_nodes) 0){ my $exclude get_exclude_nodes(exclude_nodes); #qsub -q herb.q,default.q -l h_vmem10G -l h!cn22.localh!cn23.local job.sh $cmd . -l \$exclude\ ; } if (exists $PipeLine{cpu}{$sh}){$cmd . -pe smp $PipeLine{cpu}{$sh};} if (exists $PipeLine{hostname}{$sh}){ $cmd . -l hostname$PipeLine{hostname}{$sh}; if(exists $PipeLine{serve_fa_for}{$sh}){ $cmd . -l h_vmem$PipeLine{memory}{$sh} -e $sh.$PipeLine{hostname}{$sh}.e -o $sh.$PipeLine{hostname}{$sh}.o $sh; }else{ $cmd . -l h_vmem$PipeLine{memory}{$sh} -e $sh.e -o $sh.o $sh; } }else{ $cmd . -l h_vmem$PipeLine{memory}{$sh} -e $sh.e -o $sh.o $sh; } #print $cmd; $common - print_time($cmd); #print qsub -cwd -V -q $group -pe smp $cpu -l h_vmem$mem -e $sh.e -o $sh.o $sh; }上述是我的的一个流程控制脚本的一部分 取名为control_pipeLine_test.pl运行一下perl /mnt/lustre/user/wubin/01.Program/Scripts/01.script/GeneLab/runTumor/control_pipeLine_test.pl a.sh b.sh c.sh运行结果test_0cn16Thu Sep 24 00:06:35 2026: qsub -cwd -V -q genelab.q,bigmem -l h!cn16.local -pe smp 2 -l h_vmem20G -e a.sh.e -o a.sh.o a.shtest_1h!cn16.localThu Sep 24 00:06:35 2026: qsub -cwd -V -q genelab.q,bigmem -l h!h!cn16.local -pe smp 2 -l h_vmem20G -e b.sh.e -o b.sh.o b.shtest_2h!h!cn16.localThu Sep 24 00:06:35 2026: qsub -cwd -V -q genelab.q,bigmem -l h!h!h!cn16.local -pe smp 2 -l h_vmem20G -e c.sh.e -o c.sh.o c.shtest_3h!h!h!cn16.local也就是说 exclude_nodes中元素的内容一直在变。问题出在get_exclude_nodes这个函数的foreach my $node(_)这里。对于foreach my $node(_)而言 $node只是_里面各个元素的别名 在foreach循环里面如果再修改$node那么_中对应元素的值也会跟着变。这跟_其实没关系 A, B也一样比如#!/usr/bin/perl -w use strict; use Cwd realpath; use File::Basename; use FindBin qw($Bin $Script); use Getopt::Long; use Storable; use lib /mnt/lustre/user/wubin/01.Program/Scripts/01.script/GeneLab; use Common; my $common Common - new(); my aaa qw(1 33 66); print before: .(join , aaa).\n; foreach my $a(aaa){ $a 3; } print after: .(join , aaa).\n;运行一下脚本得到结果$perl a.pl before: 13366 after: 43669foreach my $node(XXX){}循环中 不能对$node做修改。如果修改了 那么每修改一次XXX中对应元素也跟着修改一次这通常是不合理的。所以get_exclude_nodes函数中的循环应该改一下。修改方式1避免对数组的元素别名进行修改sub get_exclude_nodes{ my node_tmp (); foreach my $node(_) { #print test_1$node\n; if ($node !~ /\.local/) {$node . .local;} #$node h!$node; my $exclude_info h!$node; push(node_tmp, $exclude_info); } my $exclude join , node_tmp; return $exclude; }测试一下$perl /mnt/lustre/user/wubin/01.Program/Scripts/01.script/GeneLab/runTumor/control_pipeLine_test.pl a.sh b.sh c.sh test_0cn16cn17 Thu Sep 24 00:20:16 2026: qsub -cwd -V -q genelab.q,bigmem -l h!cn16.localh!cn17.local -pe smp 2 -l h_vmem20G -e a.sh.e -o a.sh.o a.sh test_1cn16.localcn17.local Thu Sep 24 00:20:16 2026: qsub -cwd -V -q genelab.q,bigmem -l h!cn16.localh!cn17.local -pe smp 2 -l h_vmem20G -e b.sh.e -o b.sh.o b.sh test_2cn16.localcn17.local Thu Sep 24 00:20:16 2026: qsub -cwd -V -q genelab.q,bigmem -l h!cn16.localh!cn17.local -pe smp 2 -l h_vmem20G -e c.sh.e -o c.sh.o c.sh test_3cn16.localcn17.local修改方式2 直接将数组复制一份这样虽然对复制后的数组进行了修改 但原数组不受影响。sub get_exclude_nodes_2{ my exclude_info _; #拷贝一份就跟_, 也即主程序的实参exclude_info无关了 my node_tmp (); foreach my $node(exclude_info) { if ($node !~ /\.local/) {$node . .local;} $node h!$node; #此时对 $node操作也不会影响_ push(node_tmp, $node); } my $exclude join , node_tmp; return $exclude; }运行一下$perl /mnt/lustre/user/wubin/01.Program/Scripts/01.script/GeneLab/runTumor/control_pipeLine_test.pl a.sh b.sh c.sh test_0cn16cn17 Thu Sep 24 00:24:22 2026: qsub -cwd -V -q genelab.q,bigmem -l h!cn16.localh!cn17.local -pe smp 2 -l h_vmem20G -e a.sh.e -o a.sh.o a.sh test_1cn16cn17 Thu Sep 24 00:24:22 2026: qsub -cwd -V -q genelab.q,bigmem -l h!cn16.localh!cn17.local -pe smp 2 -l h_vmem20G -e b.sh.e -o b.sh.o b.sh test_2cn16cn17 Thu Sep 24 00:24:22 2026: qsub -cwd -V -q genelab.q,bigmem -l h!cn16.localh!cn17.local -pe smp 2 -l h_vmem20G -e c.sh.e -o c.sh.o c.sh test_3cn16cn17但还是尽量不要对foreach my $node(exclude_info)中的$node进行修改这是一种不好的习惯。
