Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all
I have some executable files (in other programming language) and I am trying to build a wrapper script with perl. I have partially succeeded in the task. But I need to run three system commands(in other words three different executable files) and I could run the first and the second without anyproble. The second and the third executables are with ina foreach loop. So, it executes the first system cmd (with in the foreach loop) and exits. If I commented the first system cmd after exiting the second one runs with out any problem.


Is that as simple as the file dependencies of the second cmd from the first? Or is there a logic problem with the way I have build the script?
I hav attached the code for your opinion
#!/software/bin/perl use strict; use warnings ; use File::Copy; use File::Basename; use File::Listing; my $rootdir = $ARGV[0]; my $celfile = $ARGV[1]; my $cfile = fileparse($celfile); my $sample = $ARGV[2]; my $cdfdir = $rootdir . "/cdf"; my $celdir = $rootdir . "/cel"; my $outdir = $rootdir . "/outdir"; mkdir($cdfdir, 0755) || print "Couldn't make dir $!\n"; mkdir($celdir,0755) || print "Couldn't make Celdir $!\n"; my $cdffile = "/nfs/team78pc/Individuals_Folders/cdg/TRANSFER/viewer/p +icnicGUI_unix/src/GenomeWideSNP_6.fromDB.cdf"; copy("$cdffile", "$cdfdir/GenomeWideSNP_6.fromDB.cdf") or die "copy fa +iled $!\n"; copy("$celfile", "$celdir/$cfile") or die "copy of celfile failed $!\n +"; mkdir ($outdir,0755) || print "Couldn't create outputdir : $!\n"; chdir($rootdir) || die "Can't change directory $!\n"; my $cmd1 = "java -Xmx2G -jar $rootdir/celConverter/CelFileConverter.ja +r -m $rootdir/celConverter/Snp6FeatureMappings.csv -c $rootdir/cdf/Ge +nomeWideSNP_6.fromDB.cdf -s $celdir/ -t $rootdir/outdir/raw"; system($cmd1); my $dir = "$rootdir/outdir/output2/$sample" . "_feature.TXT"; opendir(DIR, "$rootdir/outdir/raw") || "Cannot open the directory $!\n +"; opendir(ODIR,"$dir") || "Cannot open output2directory $! \n"; foreach my $file (readdir(DIR)){ if($file =~ /feature_intensity$/){ #my $cmd = "sh run_preprocessing.sh $rootdir/Matlab_Compilet_Runtime +/v710/ $file $rootdir/info/ $rootdir/outdir/raw/ $rootdir/outdir/outp +ut/ $rootdir/outdir/ PRIMARY 0.5"; #warn "Running $cmd... \n"; #system($cmd); #outputs ploidy_3456_feature.TXT.csv foreach my $file2(readdir(ODIR)){ if($file2 =~ /^ploidy\_$sample\_feature\.TXT\.csv$/){ open(FILE, "<$dir/$file2") || "Cannot open the file $file2 $!\n"; +#output from the previous system cmd. while(<FILE>){ chomp; my ($in_pi,$in_ploidy,$in_alpha) = split(/,/); my $cmd2 = "sh run_HMM.sh $rootdir/Matlab_Compilet_Runtime/v710/ +$file $rootdir/info/ $rootdir/outdir/output/ $rootdir/outdir/ 10 $in_ +pi $in_ploidy $in_alpha"; warn "Running $cmd2\n"; system($cmd2); } close FILE; } } } }
Thanks a ton

Replies are listed 'Best First'.
Re: Running executables with perl using system command
by roboticus (Chancellor) on Jan 26, 2011 at 10:54 UTC

    First, your inner loop reads the ODIR directory all the way through, so there's nothing to read in the second iteration of the outer loop. Second, since you've opened the directory and are putting files in it while you have it open, I don't know that there's any guarantee that you won't miss a file. You could fix both problems by opening ODIR just before the start of the second loop. Alternatively, you could use a glob to find the matching filenames, rather than scanning through all of them.

    However, there's a better way: Since you already know the name of the file, there's no reason to scan through the directory for it. Instead, just open your file. Since you pass in $sample on the command line, there's no reason to use the opendir / readdir and regular expression.

    my $cmd1 = "java -Xmx2G -jar $rootdir/celConverter/CelFileConverter.ja +r -m $rootdir/celConverter/Snp6FeatureMappings.csv -c $rootdir/cdf/Ge +nomeWideSNP_6.fromDB.cdf -s $celdir/ -t $rootdir/outdir/raw"; system($cmd1); my $dir = "$rootdir/outdir/output2/$sample" . "_feature.TXT"; opendir(DIR, "$rootdir/outdir/raw") || "Cannot open the directory $!\n +"; foreach my $file (readdir(DIR)){ if($file =~ /feature_intensity$/){ #my $cmd = "sh run_preprocessing.sh $rootdir/Matlab_Compilet_Runti +me/v710/ $file $rootdir/info/ $rootdir/outdir/raw/ $rootdir/outdir/ou +tput/ $rootdir/outdir/ PRIMARY 0.5"; #warn "Running $cmd... \n"; #system($cmd); #outputs ploidy_3456_feature.TXT.csv #output from the previous system cmd. $file2 = "ploidy_" . $sample . "_feature.TXT.csv"; open FILE, "<", $dir/$file2" or "Cannot open the file $file2 $!\n"; while(<FILE>){ chomp; my ($in_pi,$in_ploidy,$in_alpha) = split(/,/); my $cmd2 = "sh run_HMM.sh $rootdir/Matlab_Compilet_Runtime/v710/ + $file $rootdir/info/ $rootdir/outdir/output/ $rootdir/outdir/ 10 $in +_pi $in_ploidy $in_alpha"; warn "Running $cmd2\n"; system($cmd2); } close FILE; } }

    I've cleaned up your indentation a little to make the code easier to follow, and used the three-argument form of open, as a reminder that it's generally accepted as the better form to use.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Hi Thanks!That make sense now and has solved the issue :) Thanks a lot once again
Re: Running executables with perl using system command
by GrandFather (Saint) on Jan 27, 2011 at 05:08 UTC

    Unless you actually use a key based lookup elsewhere in the code you may be better to use nested arrays rather than nested hashes. Consider:

    #!c:\Perl\bin\perl use warnings; use strict; use constant KANRI_01_0 => 0x00000001; # TBC use constant KANRI_01_1 => 0x00000002; # TBC use constant KANRI_02_0 => 0x00000004; # TBC use constant KANRI_02_1 => 0x00000008; # TBC use constant KANRI_03_0 => 0x00000010; # TBC use constant KANRI_04_1 => 0x00000020; # TBC use constant KANRI_04_2 => 0x00000040; # TBC use constant KANRI_04_3 => 0x00000080; # TBC use constant KANRI_04_4 => 0x00000100; # TBC use constant KANRI_05_1 => 0x00000200; # TBC use constant KANRI_05_2 => 0x00000400; # TBC use constant KANRI_06_1 => 0x00000800; # TBC use constant KANRI_07_1 => 0x00001000; # TBC use constant KANRI_07_2 => 0x00002000; # TBC use constant KANRI_07_3 => 0x00004000; # TBC use constant KANRI_07_4 => 0x00008000; # TBC use constant KANRI_07_5 => 0x00010000; # TBC use constant KANRI_08_1 => 0x00020000; # TBC my @menu = ( [Outer1 => [ [O1Inne1 => KANRI_04_1], [O1Inne2 => KANRI_04_2], [O1Inne3 => KANRI_04_3], [O1Inne4 => KANRI_04_4], ]], [Outer2 => [[O2Inne1 => KANRI_05_1]]], [Outer3 => [[O3Inne1 => KANRI_06_1]]], [Outer4 => [ [O4Inne1 => KANRI_07_1], [O4Inne2 => KANRI_07_2], [O4Inne3 => KANRI_07_3], [O4Inne4 => KANRI_07_4], [O4Inne5 => KANRI_07_5], ]], [Outer5 => [[O5Inne1 => KANRI_08_1]]], ); for my $mainMenuItem (@menu) { print "$mainMenuItem->[0]\n"; for my $subMenuItem (@{$mainMenuItem->[1]}) { print "$subMenuItem->[0] = $subMenuItem->[1] "; } print "\n"; }

    Prints:

    Outer1 O1Inne1 = 32 O1Inne2 = 64 O1Inne3 = 128 O1Inne4 = 256 Outer2 O2Inne1 = 512 Outer3 O3Inne1 = 2048 Outer4 O4Inne1 = 4096 O4Inne2 = 8192 O4Inne3 = 16384 O4Inne4 = 32768 +O4Inne5 = 65536 Outer5 O5Inne1 = 131072
    True laziness is hard work