Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Backtick caught in infinite loop

by tau1777 (Initiate)
on Jun 20, 2014 at 00:40 UTC ( [id://1090531]=perlquestion: print w/replies, xml ) Need Help??

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

Hello all,

I am trying to use backticks like so: my @result = `command --arg1=$num1 --arg2=file.log  . . . -argLast=$numLast`;

I can see from the log file that the command is processing and on some occaisions I have even seen the log file say the command was finished, however the rest of my perl script does not run, instead the command starts to run again.

I was thinking about adding something like exit if $?=0 inside of the backticks to force the script to move on, but I think this not quite right. I've read that backticks are supposed to hand over control to the parent script after it runs so I really don't even want to force it to continue.

Any thoughts on what might be going on?

I'm sorry for asking such a basic question and vague questions. I will try to provide any details you would like. But unfortunately I didn't write all of this code, and it is sort of privately owned, so I can't exactly put up the code verbatim.

Thanks very much.

Thank you all so much for your help. I figured out what was wrong thanks to, Anonymous-Monk (01:34 UTC).

It turns out there was a for loop in my code. It was about 500 lines up. I did not notice it before beacuse the original perl script that I am manipulating called an old suite of C programs that we no longer use. Using the old stuff each loop finished in 2-5 seconds. Now that we make calls to a new set of C code each for loop takes 2000s. This is certainly not an improvement and something else I have to look into.

Thank you again.

Replies are listed 'Best First'.
Re: Backtick caught in infinite loop
by zentara (Archbishop) on Jun 20, 2014 at 01:26 UTC
    If it was me, and I like to make quick guesses, hoping for an easy solution, :-) , you might just try putting
    $SIG{CHLD} = 'IGNORE';
    in your code and see if that helps the main script move on.

    As for the script running again on occaision, it maybe that the way you setup your argument list is being interpreted by the backticks and shell as some secondary argument. It can get tricky to pass an options list properly. You might want to investigate whether the line

    my @result = `command --arg1=$num1 --arg2=file.log . . . -argLast=$nu +mLast`;
    might be better setup as
    my @options = qw(--arg1=$num1, --arg2=file.log, . . . -argLast=$numLa +st ); my @result = `command @options`;
    It may take some experimentation to figure out the array element boundaries, it maybe that the first 2 options need to be in one array element. It can get mind-boggling, as I remember trying to figure out how to feed options to tar this way.

    Finally, you may want to consider running the command with IPC::Open3, or a similar IPC module, which can separate out the stdout and stderr, giving you more clues as to what is happening.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      Thanks very much.

      I'm a total noob to perl so I'm assuming that I can just put $SIG{CHLD} = 'IGNORE', right before "my @result..." and not around the beginning of the script with

       use strict;

       use File::Basename;

      etc.
        Usually, it would go right at the top of your script, right after use File::Basename. I'm guessing it would be ok before your backtick. BTW, you might want to read "perldoc perlipc".

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh
Re: Backtick caught in infinite loop
by Anonymous Monk on Jun 20, 2014 at 01:34 UTC

    Although it would certainly help, you don't have to post the original script - but you can whittle it down to a Short, Self Contained, Correct (Compilable), Example (http://sscce.org/) that reproduces the problem. Otherwise, we'll just be guessing.

    the rest of my perl script does not run

    How did you determine this? Have you tried printing something just after the backticks?

    instead the command starts to run again

    Unless the script is programmed to go back and attempt to run the command again (the backticks are inside a loop, sub, or after a label), or the script itself is being run again through some mechanism you haven't told us about, this seems really unlikely. Have you tried running the exact same command from the command line?

    I was thinking about adding something like

    Better to diagnose the problem instead of attempting solutions... Basic debugging checklist

      Thank you for all the tips. I will try to come up with a short example code. In the meantime I can answer some of your questions.

      I have not tried printing something, so this simple check is on top of my list. The backticks are not inside any sort of loop structure. I am sure, but I will double check this matter. I have not run it from the command line, but I did have sucess running it inside of a system call. The only issue was the output form the system call was not captured, and so this caused other errors.

      Oh, thanks for the debug checklist, I've definitely got #1, now to start knocking away at the rest.

Re: Backtick caught in infinite loop
by Anonymous Monk on Jun 20, 2014 at 15:24 UTC

    If there is some question of what the shell is doing to your command line, you might want to try the capturex() subroutine in IPC::System::Simple. This subroutine bypasses the shell, so you don't have to worry about sanitizing metacharacters, and your command sees exactly the arguments you pass it.

    IPC::System::Simple is not a core module, so you would have to install it yourself, or get a friendly system administrator (if any) to do it for you.

    The recommendation above to put the arguments in an array may well have merit as a troubleshooting step, so you can print them before the command. But in your specific case the qw{...} construction is of limited usefulness because it does not interpolate. You would have to build the array with something like

    my @args = ( 'command', "--arg1=$num1", '--arg2=file.log', ... "-argLa +st=$numLast" );
    . The switching between quote types in the example is a stylistic thing, since "" interpolates and '' does not, and you should do whatever your local coding standards say.

      Thank you, this will come in handy in the future for my personal perl usage.

      Unfortunately, I'm using a cluster where I don't have the ability to install modules. And if its not a core module the admins probably won't do it either.

      Furthermore, the suite of perl scripts we were using recently broke down becuase of mismangement/misunderstanding of the modules currently installed, so installing more modules is a road I really don't want to go down, right now.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1090531]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2024-04-23 12:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found