我在Linux(Ubuntu 14.04)上运行简单的Apache Web服务器,并使用一个Perl CGI脚本处理一些请求。该脚本使用“system”函数启动系统命令,但我希望它无论系统调用的结果如何都能立即返回。 我已经在传递给“system”函数的标量参数末尾添加了一个&符号(我知道这可能会导致命令注入攻击),虽然这确实使得系统命令能立即返回,但是直到底层命令完成之前,脚本仍将不会退出。如果我从Perl CGI使用“system”调用触发一个具有10秒休眠的虚假Ruby脚本,则我的Web服务器请求仍需等待10秒才能最终得到响应。我在“system”调用后放置了日志语句,并在Web请求时立即出现,所以“system”调用肯定能够立即返回,但脚本仍将停留在结尾处。这个问题类似于这个问题,但两个解决方案对我都没有起作用。以下是一些示例代码:
使用
我还尝试在脚本的末尾添加
从终端直接运行 perl CGI 脚本可以正常工作。Perl 脚本立即结束,因此这不是 Perl 的固有问题。这预示着 Apache Web 服务器会保持请求直到从
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init(
{ level => $DEBUG, file => ">>/var/log/script.log" } );
print "Content-type: application/json\n\n";
my $cgi = CGI->new();
INFO("Executing command...");
system('sudo -u on-behalf-of-user /tmp/test.rb one two &');
INFO("Command initiated - will return now...");
print '{"error":false}';
编辑:使用
sudo -u
执行命令是因为 Apache 用户 www-data
需要获得脚本所有者的执行权限,我已经相应地更新了我的 sudoers 文件。这不是我遇到问题的原因,因为我也尝试将脚本所有权更改为 www-data
并运行 system("/tmp/test.rb one two &")
,但结果仍然相同。
编辑2:我还尝试在脚本的末尾添加
exit 0
,但没有任何区别。可能脚本立即退出,但 Apache 服务器一直保持响应,直到 perl CGI 调用的命令完成吗?或者操作系统的某些设置或配置会导致问题?
编辑3:从终端直接运行 perl CGI 脚本可以正常工作。Perl 脚本立即结束,因此这不是 Perl 的固有问题。这预示着 Apache Web 服务器会保持请求直到从
system
中调用的命令完成。为什么?
system
调用的数组版本,以防止命令注入。无论如何,没有一个这些解决方案适用于我,导致与本问题描述相同的行为。此外,当我接受那个问题的答案时,我没有进行适当的测试,所以我没有意识到它仍然无法正常工作。 - RTF