linux-在不等待系统调用返回的情况下结束perl脚本

我正在Linux(Ubuntu 14.04)上运行一个简单的apache Web服务器,并使用perl CGI脚本处理一些请求.该脚本使用系统功能启动系统命令,但是我希望它立即返回,而不管系统调用的结果如何.

我一直在传递给系统的标量参数的末尾添加“&”号(我知道命令注入攻击的含义),尽管这确实会导致系统命令立即返回,但脚本直到下层脚本仍不会退出命令已完成.

如果我使用来自perl CGI的系统调用以10秒钟的睡眠时间触发了一个虚拟的ruby脚本,那么我对Web服务器的请求仍会等待10秒,直到最终获得响应.我在系统调用后放置了一条日志语句,该语句在发出Web请求时立即出现,因此系统调用肯定会立即返回,但脚本仍在最后等待.

This question与之类似,但是没有一个解决方案对我有用.

这是一些示例代码:

#!/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一二&”),但是结果是相同的.

编辑2:
我也尝试将出口0添加到脚本的最后,但这没有任何区别.脚本是否有可能立即退出,但是apache服务器会一直保持响应,直到调用perl CGI的脚本完成?还是操作系统的某些设置或配置导致了此问题?

编辑3:
直接从终端运行perl CGI脚本可以正常工作. perl脚本立即结束,因此这不是Perl固有的问题.这大概只能意味着Apache Web服务器将保留请求,直到从系统调用的命令完成为止.为什么?

解决方法:

Web服务器创建一个管道以接收响应.在完成请求之前,它等待管道到达EOF.当关闭所有编写器句柄副本时,管道达到EOF.

管道的写入器端设置为子代的STDOUT.该文件句柄被复制为外壳的STDOUT,然后再次复制到mycmd的STDOUT.因此,即使CGI脚本和外壳程序结束并因此关闭了文件句柄的末端,mycmd仍将句柄保持打开状态,因此Web服务器仍在等待响应完成.

您需要做的所有事情都是关闭管道的writer端的最后一个句柄.或者更确切地说,可以通过将不同的手柄附加到mycmd STDOUT上来避免将其放在第一位.

mycmd arg1 arg2 </dev/null >/dev/null 2>&1 &
上一篇:PHP-Alias指令可能永远不会匹配,因为它与早期的Alias重叠


下一篇:Python CGI脚本:OSError:[Errno 8] Exec格式错误