资讯详情

perl踩坑系列之foreach

发布时间:2026/9/25 21:49:03

500+
企业客户服务经验
120+
行业领域内容覆盖
3000+
原创页面设计沉淀
98%
客户满意度

perl踩坑系列之foreach

先上代码#!/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进行修改这是一种不好的习惯。
热门专题

继续阅读更多专题内容

围绕企业服务、数字化转型与官网运营的常青话题,持续输出深度内容

企业官网建设指南 企业托管服务模式 财税政策与解读 企业数字化转型 官网SEO与获客 网站安全与运维
配套服务

读完这篇文章,了解更多服务

从整站搭建到SEO布局,17项核心服务助您打造高转化的企业官网

01

企业托管整站搭建

从信息架构到栏目预留,搭建可生长的企业站点骨架,每个页面独立原创设计。...

了解详情
02

规整可信网页设计

雪地靴温暖风原创设计,金属铜线条贯穿全页,拒绝通用模板与AI流水线。...

了解详情
03

企业服务SEO布局

关键词体系与语义化结构,从建站源头为搜索排名而生。...

了解详情
04

业务预约咨询表单

多场景表单与线索收集体系,把访问流量转化为可追踪的销售线索。...

了解详情
05

企业服务站点运维

安全巡检、数据备份与内容更新支持,全年守护网站稳定运行。...

了解详情
06

全终端商务适配

电脑、平板、手机一致呈现,移动端体验与转化同样出色。...

了解详情
需要专业建议?

让专业顾问为您解读行业趋势

关于企业官网建设、SEO获客与数字化转型的任何疑问,欢迎一对一咨询我们的专业顾问。