http://qs321.pair.com?node_id=906355


in reply to How to "transfer control" to child process?

I have some comments on the script itself, even though that's not what you were posting about.

I already mentioned use strict; use warnings. But also, what version of Perl are you using? If it is reasonably up to date, you can use the new "given/when" construct.

You are not declaring your variables. This will be caught by strict, and mis-spelled variables is one of the easiest mistakes to make and find automatically.

You are using explicit variable name in constructs that use $_ implicitly, but still using $_ for the variable. If you are going to use a name, use a named local variable. Or if you use $_, leave it off. For serious programming (as opposed to quick one liners or one-time-use scripts) you use the explicit form as you did, but use a name.

foreach my $line (@configFile) { next if $line =~ /^\s*$/; ...
You don't need the parens around the condition in the suffix (statement modifier) form. I don't see where @configFile is coming from. It will be empty! So there might be stuff you're not showing in the example.

Now the cool up-to-date stuff. If you use Perl 5.10 or higher, you can use given/when. But, that works with a foreach as well, so I'll revert to using the implicit $_ form:

foreach (@configFile) { chomp; # careful of last line in file next if /^\s*$/; # empty line next if /^\s*#/; # comment line when (/^\s*ScriptName:\s+\S+\s*$/) { ($tag,$scriptName) = split(); } when (/^\s*LogFileName:\s+\S+\s*$/) { ($tag,$logFileName) = split(); } when (/^\s*NumberOfSteps:\s+[0-9]+\s*$/) { ($tag,$numberOfSteps) = split(); } when (/\s*Restart:\s+\S+\s*$/) { ($tag,$restart) = split(); } when (/^\s*Step\s+[0-9]:/) { $stepNum = $_; $stepNum =~ s/^\s*Step\s+([0-9]+):.*$/$1/; $command = $_; $command =~ s/^\s*Step [0-9]:+\s+//; $step[$stepNum] = $command; } default { print STDERR "Error: unknown config file line:\n"; print STDERR " $_\n"; $error = 1; } }
Now the use of split splits on whitespace, but you already went through the string with the regexp and found the space. So use the results of the regexp instead of splitting again:
when (/^\s*(ScriptName:)\s+(\S+)\s*$/) { $tag= $1; $scriptName= $2; }
Note that you are requiring a space after the colon and before the name. If that is an artefact of your use of the simple split, you don't need that this way. Change the + to a * if you like.

Note finally that [0-9] is common enough to have an optimized abbreviation: \d for digit.

The stuff for Step is rather convoluted. In the same mold that I just showed, try:

when (/^\s*Step\s+(\d):\s*(.*)/) { $stepNum = $1; $command = $2; $step[$stepNum] = $command; }
But there is really no reason to note the $tag in these lines, as it was just a byproduct of your use of split. This limits you to 10 steps (0 through 9) as single digits. If you used \d+ it would be open ended.

But your following loop starts at 1, not zero. So even though you accept a step 0, you never use it.

There's really no need to specify the "number of steps". Just use whatever is in the array when you've read it:

foreach my $command (@step) { next unless defined $command; # skip unused numbers my $ret= system ($command); ... }

Replies are listed 'Best First'.
Re^2: How to "transfer control" to child process?
by VingInMedina (Acolyte) on May 24, 2011 at 01:46 UTC

    Thank you for taking the time to look this over. The problem was in the script that I was using to invoke my program. When I called my program using the -C option to specify the configuration file, instead of reading it from STDIN, it worked as I expected. (reading the file was from a section of code I didn't include)

    The version of Perl I am using is 5.8.4, which is the standard version for Solaris 10. Using 5.10 is not an option.

    My coding style is not as tight a some people. I have a tendancy to be more verbose in my coding than others, but this is born out of a necessity to make the code understandable to people who will have to maintain it after me.

    Yes, there some bugs in the section reading the configuration file which I had not yet fully corrected. My focus was on trying to figure out why the system call wasn't working as I expected it to work. Thanks for pointing those out.

    Thanks again for your help and for your time.