无法在cgi中执行外部命令

标签 c perl cgi

我的文件 .pl 中有这行代码

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

read_image 是一个 C 可执行文件,它在命令行中运行良好,但是当我在网络服务器中运行我的 .pl 文件时,这一行不起作用,它的功能是将一些数据写入文件,所以我可以看看它是否有效

我也试过``,还是不行

有人有想法吗?

最佳答案

我认为这是因为当您的网络服务器运行您的 CGI 时,它会从某个奇怪的目录(/var/www/htdocs/ 或其他目录)运行。那么你的 read_image 也应该在那个目录中,因为 ./read_image.
./表示当前目录,不一定是你的.cgi所在的目录。
我建议使用 Perl 模块 FindBin :

您的 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 解析为您的 .cgi 所在的路径——无论您从何处调用它。这是一个非常方便的模块,也可以用来修改@INC 路径以找到您自己的模块:

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

这样 MyModule.pm 应该在 $current_script_path/../lib 中。非常方便。


附录

随着讨论的深入,这显然不仅是 apache 能否找到 read_image 命令的问题,而且还是 read_image 能否找到 命令的问题>wget 它试图执行的命令。

正如@CDahn 已经在评论中指出的那样,出于安全原因,apache 在有限环境 中运行CGI 脚本等。如果你从你的 shell 运行 read_image,那么你就有了一个完整的工作环境,比如说,PATH 包括 15 个不同的目录(比如 /usr/bin:/opt/bin:/usr/share/bin:/usr/local/bin:...,随便)。当 apache 运行你的脚本时,PATH 可能只包含 2 或 3 个绝对必要的目录,例如/usr/bin:/usr/local/bin。其他环境变量也是如此。

你可以用一个简单地回应当前环境的小.cgi脚本来验证这一点,比如

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

(摘自http://perldoc.perl.org/functions/each.html)
从您的浏览器调用此 .cgi,您将看到不同之处。

当您的 read_image 找不到 wget 命令时,可能是因为 wget 位于 apache 不知道的 PATH 中。我不会教 apache 关于附加目录(坏主意),而是在你的 read_image 程序中给出 wget 命令的完整路径。从您的终端窗口运行

$ which wget
/usr/bin/wget

并在从您的 read_image 调用 wget 时使用该路径。

关于无法在cgi中执行外部命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36101900/

相关文章:

c - 我怎样才能让这个蛮力算法逐步检查字母

c - 函数指针中标记之前的预期标识符

c - OpenSSL DigestInit_ex

perl - Noweb 不交叉引用左侧由 @ 分隔的 Perl 标识符

Perl 构建、单元测试、代码覆盖率 : A complete working example

delphi - 调试 Windows CGI 的最佳方法

C 按位运算符

json - Perl XML2JSON : How to preserve XML element order?

spring - Spring MVC中如何访问proxy.cgi文件

mysql - 为什么 Encode::decode ('UTF-8' , $var) 一切都已经在 UTF-8 中时仍然需要?