http://www.perlmonks.org?node_id=512019


in reply to calling a perl script within a perl script

I get the impression that you're approaching this problem from a shell scripting perspective. There's nothing wrong with this, but there may be other more elegant solutions you're overlooking.

For example, can you rewrite test_script.pl into a module which provides a subroutine you can then call for each filename? If so, this code would become a whole lot easier. Don't be scared of subroutines and modules, they're a lot faster than forking off processes which is what this code is doing.

It's hard to give you a good solution while test_script.pl remains a black box. Does it return input that you need, what does it return upon failure? Answers to these kind of questions can help us a great deal.

I think you'll find that the following code does what you have asked for, but I'm not convinced that it's actually the correct solution.

#!/usr/bin/perl -w use strict; # any other setup... my $test_script = "/home/com/begp/test_script.pl"; my $dirtoget="/home/com/begp/testinvs"; # Get all the files which end with .txt (or as appropriate) my @files = glob("$dirtoget/*.txt") foreach my $file (@files) { # Skip if it's a directory or other "non-file" next unless -f $file; my $return = `/usr/bin/perl -w $test_script $file`; # Check if there was an error if($?) { if($? == -1) { die "Failed to run program: $!"; } else { die "Exit value was: " . ($? >>8); } } # Else do whatever is required with the return value # in $return }

I use glob to ensure that you don't end up accidently working with files which aren't the kind you're looking for. Likewise, just in case files (or directories) are misnamed I also check that the file is a "normal file" which rules out directories, devices, streams etc.

Be aware that this code can open you to security problems. For example if evilly named files are inserted into that directory, bad things can happen. For example, consider the following possible file name:

aa; rm -rf /; cat foo.txt

As things in backticks *always* go past the shell this will be interpretted as if you'd typed on your command line:

%> /usr/bin/perl -w /home/com/begp/test_script.pl aa %> rm -rf / %> cat foo.txt

Obviously this is a bad thing and my tests above will not stop this from happening.

If you can rewrite test_script.pl into a module which provides a subroutine which does the work you need, then that's almost certainly the way to go. If not, turn on Taint mode and check your filenames explicitly.

Hope this helps

jarich