Perl script 'system' linking to local shell script not working

Trying to figure out why this works:

printpwd.pl

#!/usr/bin/perl
use CGI::Carp qw( fatalsToBrowser );
print "Content-type: text/html\n\n";


$A = system("pwd");
$A = `pwd`;
print "$A\n";

^^actually that works/breaks if that makes any sense.. i get the working directory twice but when i comment out the second variable declaration $A = `pwd`;.. it prints out the success 0. :o But at least it printed something out from the cl. Now this confuses me...

hellow.pl

#!/usr/bin/perl
use CGI::Carp qw( fatalsToBrowser );

print "Content-type: text/html\n\n";

system("hellow");
 
open(HTMLFILE, "hellow.html") || die "
  <center><H3>Sorry, I cannot open HTML pollfile.</H3></center>";
while (read(HTMLFILE, $buffer, 16384))  #Print the Poll HTML file
{
    print $buffer;
}
close(HTMLFILE);

hellow.sh

#!/bin/sh

echo "</head>
<body text="#FF0000" bgcolor="#000000">
<b>TEST</b>" > hellow.html

The second pair of scripts, when i run hellow locally it works fine generating the html fine but when i remove it and try to have it called from the perl script, perl doesn't err on line 6, it complains of line 8??? grrrr :mad:

Perl doesn't auto-complain if something non-critical doesn't work. If you want to call a shell script, but it can't find it (say, because you forgot to type the '.sh' that's part of the filename), system will fail with an error code, which you as the programmer have to catch and act upon (example in perldoc -f system).

And the ouput of the file can be written simpler as

open (HTMLFILE, "hellow.html");
while ($buffer = <HTMLFILE>)
{
    print $buffer;
}
close HTMLFILE;

or even

open (HTMLFILE, "hellow.html");
print while HTMLFILE;
close HTMLFILE;

yea i know what you mean about perl and it not complaining but i guess that's the reason for the rant. perl doesn't care about my 'critical' step in the code. but i'm not lazy, i'll figure it out some way.

I tried to simplify the output as you suggested in both examples but for some reason my browser just spins when I try to load the page even with the system call commented out. I had to kill this on my box.

52977 www           1 111    0  2796K  2172K CPU0   0   0:21 92.61% perl5.8.7

Looking at the man, i tried to follow but got lost at `$?`

So my next task is to learn how to take this tidbit to test this and any other future shell scripts against perl. My command 'hellow' still works fine when typed directly into the cl. I forgot to mention that the hellow.sh was copied, moved, and exported into my shell env ~/home/root/bin.. that's why i'm somewhat dumbfounded... pwd works but hellow doesn't still and i'm clueless. I'm hoping that testing it in perl with the code above might give me some more info. Need some input on what to put where. Should i just replace all `?` to `hellow`??

$? is a variable that holds the return code of the last system command, pipes, ..., pretty much the same as in the shell. By inspecting that you can check if your command succeded or not.

As for your 'hellow' script, your user might have the path to it in it's environment. But the user the webserver is running as (www) most probably doesn't. So it's always a good idea to use the absolute path, and ensure that the user 'www' has read & execute rights on the file. If you still have problems, add the 'holy trinity' to your script, and run it on the command line.

# The 'holy trinity'
use strict;
use warnings;
use diagnostics;

As for Perl spinning out of control: it might have to do with the unchecked open. I left out the success check in my examples for brevity, but you should always check the return code of it.

hehe thanks pludi, newbie error :o www didn't have the proper permissions.. but let me ask this.. the holy trinity i found quite useful. I fixed the variable declaration it complained about with 'buffer' and it pointed out the permissions error. Without the permissions detail I would've been lost.

Now I know that the symbol declaration issue wasn't the source of my problems but is it generally good practice to check/clean up perl scripts using it?? or do ppl generally ignore some entries they know are common and are not an issue since when you ask it to be strict it's only doing what you told it?

As a rule, I use two of them in every script (strict and warnings), 'diagnostics' when developing / debugging but I drop it for production code. Sure, it might be more comfortable to code without them, but sooner or later you'll miss a typo that has a nasty side effect. Some warnings may be ignored (such as "uninitialized value in concatenation"), except that they might clutter your output/log and distract from any serious message.

I've got a couple other tips:

  • Use perl -c occasionally. It won't run your script, but check the syntax. Good to catch any missing semi-colons.
  • Use perltidy on your code to make it easier to read. Does a syntax check, too.
  • Occasionally, run perlcritic for some best practices.