zhao_zilong
zhao_zilong

Reputation: 1

can't execute external command in cgi

I have this line code in my file .pl

system("./read_image http://echopaw.fr/wp-content/uploads/2015/09/animals-41.jpg");

read_image is a C executable file, it works well in command line, but when I run my .pl file in web server, this line didn't work, its function is to write some data into a file, so I can see if it works

I also tried `` , but it still didn't work

anyone gets some ideas?

Upvotes: 0

Views: 560

Answers (1)

PerlDuck
PerlDuck

Reputation: 5730

I think it's because when your webserver runs your CGI then it does so from some wierd directory (/var/www/htdocs or / or whatever). Then your read_image is also expected to be in that directory because of the ./read_image.
./ means current directory, which is not necessarily the directory where your .cgi is located.
I'd suggest using the Perl module FindBin:

your cgi:

...
use strict;
use warnings;
use FindBin;

...
system("$FindBin::Bin/read_image http://echopaw.fr/wp-content/uploads/2015/09/animals-41.jpg");

$FindBin::Bin resolves to the path where your .cgi is located -- no matter where you call it from. It's a quite handy module and can also be used to pimp the @INC path to find your own modules:

use lib "$FindBin::Bin/../lib";
use MyModule;

This way MyModule.pm is expected to be in $current_script_path/../lib. Very convenient.


Addendum

As the discussion evolves this is apparently not only a problem of whether apache can or cannot find the read_image command but also of whether read_image in turn can find the wget command which it tries to execute.

As @CDahn already noted in a comment apache runs CGI scripts and the like with a limited environment for security reasons. If you run read_image from your shell, then you have a fully working environment with, say, PATH including 15 different directories (like /usr/bin:/opt/bin:/usr/share/bin:/usr/local/bin:..., whatever). When apache runs your scripts, PATH may only contain 2 or 3 directories that are absolutely necessary, e.g. /usr/bin:/usr/local/bin. The same applies to other environment variables.

You can verify this with a little .cgi script that simply echoes the current environment, like

while (my ($key,$value) = each %ENV) {
    print "$key=$value\n";
}

(Taken from http://perldoc.perl.org/functions/each.html)
Call this .cgi from your browser and you'll see the difference.

When your read_image cannot find the wget command then probably because wget is located in a PATH apache doesn't know of. Instead of teaching apache about the additional directory (bad idea), I would give the full path to wget command in your read_image program. From your terminal window run

$ which wget
/usr/bin/wget

and use that very path when calling wget from your read_image.

Upvotes: 2

Related Questions