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.
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.
| [reply] [d/l] [select] |
|
| [reply] [d/l] [select] |
|
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".
| [reply] |
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
| [reply] [d/l] [select] |
|
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.
| [reply] |
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. | [reply] [d/l] [select] |
|
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.
| [reply] |
|
|