Re: How to execute external script from CGI
by hippo (Archbishop) on May 22, 2020 at 08:32 UTC
|
my $out = `perl /var/www/html/portfolio/loadCSV.pl --L --Q`
print "$out";
The second problem here is that the top line is not terminated in a semi-colon. The first problem (as others have addressed) is that you are attempting to shell out from perl to perl.
"It doesn't work" is as useful to a developer as "I'm ill" is to a medic. Try to be specific. SSCCE is best.
| [reply] [d/l] |
|
|
Thanks for pointing out I was missing a semicolon.
| [reply] |
Re: How to execute external script from CGI
by perlfan (Parson) on May 22, 2020 at 04:22 UTC
|
One of the absolutely most offensive things I see wrt Perl is the practice of calling a Perl script from a Perl script.
Why? Other than just bad taste, you are unnecessarily burdening the operating system with the overhead of creating an additional perl interpreter, invoking all book keeping required for spawning and tracking child processes and memory. Oh, but it's just one extra process, you say! Well you keep doing that kind of thing and your CGI script grows in popularity and size - suddenly your server load is about 8,000 times what it should be. Do not laugh, I have seen it happen and continue to happen.
Turn loadCSV.pl into a modulino - it can be done in very few lines, even if it's a monolitic Perl script from 1974.
End result in your caller (not the best practice but will save you an OS process fork:
use FindBin ($Bin);
require qq{$Bin/relative/../path/to/loadCSV.pl};
my $out = your::modulino->run( (qw/-L -Q/) );
print $out;
There are a million places to find informatin on modulinos, it's pretty much as simple as:
package your::modulino;
use strict;
use warnings;
# Note: I know this is awful but it's better than what OP is doing now
print __PACKAGE__->run(\@ARVG) if not caller;
sub run {
my $self = shift;
local @ARGV = @_;
# shove nearly all loadCVS.pl in here, getopt and all with ONE excep
+tion
# ...
# convert all of your "print" statements such they create the string
+ you
# were going to print, then:
return $formerly_printed_stuff;
}
1;
The above is dirty, but better what you're doing. And it provides the basis for really creating a well done modulino. Or better yet, an actual Perl module where the CLI version becomes a 3 line script calling the dern module you just peared off. | [reply] [d/l] [select] |
|
|
Hi I have already a module for this...I did not show the whole framework. Thanks for commenting
| [reply] |
|
|
We can only go by what you post. From your other posts I can assume you're coming here for wisdom, and I am happy to oblige. If you have updated code, post it. Mostly what people what to see here is that you're learning - or at least trying. We're all here to learn. That's why I am here.
| [reply] |
|
|
| [reply] |
|
|
So I guess a modulino written in Moo is triple evil? xD
It's a handy tool on the way to full modularization. There's nothing gimmicky about it unless you consider 5% of the work and 95% of the benefit of full modularization a con.
In a legacy environment, this can mean the difference between $20,000 worth of new hardware versus about 1 hour of developer time. I've scene both scenarios play out, with the former still required quite a bit of refactor.
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in.
|
Re: How to execute external script from CGI
by marto (Cardinal) on May 22, 2020 at 07:55 UTC
|
If you are using CGI consider the alternatives. I find thatMojolicious makes it easy to do the right thing. A route that runs the code you have in your external script and renders the output in the browser would be trivial, given you already have the code.
| [reply] |
Re: How to execute external script from CGI
by Anonymous Monk on May 22, 2020 at 03:12 UTC
|
use Capture::Tiny qw/ capture /;
sub Download {
my @cmd = ( 'wget', '--help' );
my( $stdout, $stderr, $exit ) = capture {
system { $cmd[0] } @cmd;
};;
die "( $stdout, $stderr, $exit )";
}
| [reply] [d/l] |
|
|
Hi, thanks for your advice. I did try this code:
#updateQuotes.pl
use strict;
use warnings;
use Capture::Tiny qw(capture);
print "Content-type: text/html\n\n";
my $cmd = `C:\\batchfiles\\getUpdates.bat`;
my ($stdout, $stderr, $exit) = capture {
system( $cmd );
};
print "stdout = $stdout<br> stderr = $stderr <br> exit = $exit";
The batch file did execute....however I got the following output
Error from open(IO::Handle=GLOB(0x1501b30), <&STDIN): Bad file descrip
+tor at C:/Strawberry/perl/vendor/lib/Capture/Tiny.pm line 107. Captur
+e::Tiny::_open(IO::Handle=GLOB(0x1501b30), "<&STDIN") called at C:/St
+rawberry/perl/vendor/lib/Capture/Tiny.pm line 184 Capture::Tiny::_cop
+y_std() called at C:/Strawberry/perl/vendor/lib/Capture/Tiny.pm line
+357 Capture::Tiny::_capture_tee(1, 1, 0, 0, CODE(0x1cb9c8)) called at
+ C:\inetpub\wwwroot\mywebsite\admin\updateQuotes.pl line 11
| [reply] [d/l] [select] |
|
|
That's because you are taking the output from C:\\batchfiles\\getUpdates.bat and then trying to run that again as another command. That is almost certainly wrong. Do not use backticks when assigning to $cmd, use single quotes. Better yet, use an array instead just like our anonymous brother showed you.
Best by far, of course, is not to run the subprocess at all but do what you need to do within the one perl process.
| [reply] [d/l] [select] |