http://qs1969.pair.com?node_id=7248

jwielgos has asked for the wisdom of the Perl Monks concerning the following question:

This is one of those "it shouldn't do that" kind of things. I've got a script that works fine when run as user www from a shell prompt, but fails when called via CGI (which also runs as www). Instead of generating a GIF file, the system command just returns an empty string and does nothing. It does not appear to be a problem with: the command itself, string interpolation, failure to execute the command, or user permissions. My best theory is, when running as a CGI, there is a subtle change between the string I put in backticks, and the command that actually gets passed to the system, probably related to argument parsing. But I can't pin down exactly what's happening. Evidence in support of this: 1) The script works perfectly from a shell prompt (both C and bourne), under the same user id as the web server uses. 2) Earlier backtick statements work just fine, under both shell and CGI. 3) When I remove all the arguments from the command I'm passing, I get the "help screen" output, as expected. 4) If I copy the string that is put in backquotes, and paste it into a shell window, it runs just fine. 5) I've tried using the system() command in place of backticks, both passing the entire string in and separating out the individual arguments as separate strings, with no change. This is the snippet that is behaving so strangely.
srand (time ^ $$ ^ unpack "%32L*", `ps axww | gzip`); my $image_output = "/tmp/grads_www/" . $function_name . "_" . time + . "_" . int(rand 1000); my $convert_to_gif_string = "/usr/homes/joew/ImageMagick-5.1.1/convert -rotate 90 $image_outpu +t.ps $image_output.gif"; $output .= "SHELL >> $convert_to_gif_string\n"; $output .= `$convert_to_gif_string`; if (open IMAGE_FILE, $image_output . ".gif") { print $query->header('image/gif'); while (<IMAGE_FILE>) { print; } } else { print $query->header('text/plain'); print $output; print "\nfailed on open: $image_output.gif\n"; }
Output when run from shell is the contents of the GIF file. Output when run as CGI is: SHELL >> /usr/homes/joew/ImageMagick-5.1.1/convert -rotate 90 /tmp/grads_www/meteo_955384773_91.ps /tmp/grads_www/meteo_955384773_91.gif failed on open: /tmp/grads_www/meteo_955384773_91.gif Anyone know what is going on? Or even any ideas on a work-around, or further tests to run? I'm completely stumped. FYI, if you can't tell, I'm using CGI.pm to handle CGI stuff. Thanks very much, -Joe

Replies are listed 'Best First'.
Re: mysterious backticks/system() behavior in CGI script
by btrott (Parson) on Apr 10, 2000 at 21:42 UTC
    Hmm. Well, this may seem like a silly question, but are you sure that the PS file exists when run as a CGI script? How does that PS file get there, after all? That's not really apparent from your code.

    So I'd put in a

    print "PS file doesn't exist!" unless -e $image_output . ".ps";
    Perhaps also print out your environment and see if anything looks weird or wrong.

    Also, check the $? variable after you use the backticks. From perlvar:

    The status returned by the last pipe close, backtick (``) command, or system() operator. Note that this is the status word returned by the wait() system call (or else is made up to look like it). Thus, the exit value of the subprocess is actually ($? >> 8), and $? & 255 gives which signal, if any, the process died from, and whether there was a core dump. (Mnemonic: similar to sh and ksh.)
    Also, you may want to check out PerlMagick, which provides a Perl interface to ImageMagick. So, presumably, you won't have to bother yourself with running system commands. One of Randal Schwartz's Web Techniques columns uses PerlMagick to create thumnbails on the fly, so you might take a look at that.
Re: mysterious backticks/system() behavior in CGI script
by turnstep (Parson) on Apr 10, 2000 at 21:39 UTC

    Quick thoughts:

    Try looking at the $! variable in your final else loop to see *why* the open failed. Rewrite the open line as:

    if (open IMAGE_FILE, "$image_output.gif")

    Run the script with a -wT and see if that tells you anything.

    Check the path that the script runs as. This will be different from the command line path.

      Thanks for the -T tip, there were indeed some tainted variables. I fixed my $ENV("PATH"), and switched everything to use system(@list) instead of ``s. And I still don't know why, but between those two, somehow the problem went away. I'm not going to question a miracle, but there's definitely a lesson here: don't use ``s unless you really have to.. Anyway thanks everyone. Monks rock the house!
Re: mysterious backticks/system() behavior in CGI script
by chromatic (Archbishop) on Apr 10, 2000 at 23:22 UTC
    Aside from seconding the use of PerlMagick, the only other thing I can think of is putting $! in the "failed to open" line, so you can check the exact error reported by the open call.

    I did some testing on my machine, and everything else in that snippet looks okay. (ImageMagick doesn't give me any output when I try that exact line, either.)

    Maybe the whole process is chroot()ed? That's just a stab in the dark.