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

Hello, I've got a quick question regarding the use of system(). I've written a number of perl scripts that I've combined into one program with each smaller script assigned to a subroutine. Between these subroutines I use system() to run a python script that generates txt files that subsequent perl subroutines need to use. My issue is that after I use system(), the next perl subroutine opens the python generated file (I assume, I have it set to die if it doesn't), but generates an empty output file. If I disable the system() line and run the program again with the original python generated file, it works fine. Not sure what to do here... Any suggestions?

Replies are listed 'Best First'.
Re: system() issue
by davido (Cardinal) on Dec 13, 2013 at 03:04 UTC

    Any suggestions?

    Boil it down to the smallest possible test case that demonstrates the behavior you're describing, and post that code here. Keep it to less than 40 lines of code (I usually say less than 20, but you've got several moving pieces, and that complexity might warrant 40 lines to demonstrate).

    Code is needed, otherwise we can only guess. We don't necessarily need to see your program. We just need to see a small example that is complete enough to compile and demonstrate the behavior, while eliminating anything unrelated to the problem.


    Dave

      davido is right. You need to provide more information than the vague description you gave.</P.

      It sounds like you have only taken the first steps in troubleshooting your problem. Do you test the return value from system() to determine if it ran successfully? Are you using of system() properly? What do you know about the python program's execution when run via system()?

      We can't help you with so little information.

        Sorry, you will have to forgive me, I'm biologist with only a little computer knowledge. Here's a bit of code:

        #!/usr/bin/perl -w
        use strict; &sub1; #generates a text file (rep_set.txt) system('python //macqiime/QIIME/bin/assign_taxonomy.py -i rep_set.txt +-o .'); #generates second txt file &sub2; #reads the second text file

        So, all three work on their own, but when I try to run them together, sub2 gives me a blank output even though the first two parts generate the appropriate files. I'm hoping that I am simply using system() wrong... The subroutines simply open a txt file, capture some data from it, and print it out in a different format. I can provide them if need be, but since they work fine individually, I've left them out for simplicity

Re: system() issue
by vinoth.ree (Monsignor) on Dec 13, 2013 at 05:02 UTC
    Hi,

    My suggestion is, Check the exit status of the command , which is set in the special variable $?. To get the real exit status of the command you have to shift right by 8 the value of $? ($? >> 8).

    If the value of $? is -1, then the command failed to execute, in that case you may check the value of $! for the reason of the failure.


    All is well

      OK,I've checked the exit values of all of the components of the script and they all exit with a status of 0. However, when trying to make my script smaller, I realized that it works fine if I simply have the first subroutine print a txt file. So it seems to me that the issue has to due with this subroutine:

      sub rep_set{ open(FILE, "Superior_seqs2.txt") ||die; $/=">"; my%hash=(); my$hashref=\%hash; while(<FILE>){ if($_ =~ /^(.+?)\((\d+)\)(.+)\n(.+)/){ my$site=$1;my$count=$2;my$qiime=$3;my$seq=$4; $hashref -> {$seq}{$site}=$count; }else{ print "ERROR!\n" } } open (TABLE, ">>OTU_TABLE.txt")||die; open (REP,">>rep_set.txt")||die; my$seq_label=0; for my$seq_key(keys %hash){ $seq_label++; print REP ">$seq_label\n$seq_key\n"; print TABLE ">$seq_label\t"; for my$site_key(keys %{$hash{$seq_key}}){ my$counts="$hash{$seq_key}{$site_key}"; #print "$counts\n"; for(my$i=0;$i<=$counts;$i++){ print TABLE "$site_key\t"; } } print TABLE "\n"; } close FILE;close TABLE;close REP; }

      The file that is being opened has the following format:

      >ZZ2(12)orig_bc=GTAGCAACGTC new_bc=GTAGCAACGTC bc_diffs=0 TACGAAGGGACCTAGCGTAGTTCGGAATTACTGGGCGTAAAGCGCGCGTAGGCCGTTGAGTTAGTTAATT +GTGAAATCCCAAAGCTTAACTTTGGAACTGCAATTAAAACTGCTCGACTAGAGTTTGATAGAGGAAAGC +GGAATACATAGTGTAGAGGTGAAATTCGTAGATATTATGTAGAGCACCAGTTGCGAAGGCGGCTTTCTG +GATCAACACTGACGCTGAGGCGCGAAAGTATGGGTAGCAAAGAGG >ZZ2(6)orig_bc=GTAGCAACGTC new_bc=GTAGCAACGTC bc_diffs=0 TACGAAGGGACCTAGCGTAGTTCGGAATTACTGGGCGTAAAGCGCGCGTAGGCCGTTGAGTTAGTTAATT +GTGAAATCCCAAAGCTTAACTTTGGAACTGCAATTAAAACTGCTCGACTAGAGTTTGATAGAGGAAAGC +GGAATACATAGTGTAGAGGTGAAATTCGTAGATATTATGTAGAACACCAGTTGCGAAGGCGGCTTTCTG +GATCAACACTGACGCCGAGGCGCGAAAGTATGGGTAGCAAAGAGG >ZZ2(15)orig_bc=GTAGCAACGTC new_bc=GTAGCAACGTC bc_diffs=0 TACGTAGGGACCTAGCGTAGTTCGGAATTACTGGGCGTAAAGCGCGCGTAGGCCGTTGAGTTAGTTAATT +GTGAAATCCCAAAGCTTAACTTTGGAACTGCAATTAAAACTGCTCGACTAGAGTTTGATAGAGGAAAGC +GGAATACATAGTGTAGAGGTGAAATTCGTAGATATTATGTAGAACACCAGTTGCGAAGGCGGCTTTCTG +GATCAACACTGACGCTGAGGCGCGAAAGTATGGGTAGCAAAGAGG

      it has ~39,000 entries

        To avoid potential headaches, always localize assignments to global variables like $/.

        local $/ = '>';

        That way, the value of $/ will be automatically restored after the sub exits. Later parts of your program might not like having a weird line terminator dropped on them.

        Also good practice to localize $_ if you're using it for that type of while loop.

        local $_; while (<FILE>) {