完perl脚本,而无需等待系统调用返回 [英] End perl script without waiting for system call to return

查看:258
本文介绍了完perl脚本,而无需等待系统调用返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我运行一个简单的Apache Web的Linux上,一个Perl CGI脚本处理一些请求的服务器(Ubuntu的14.04)。该脚本启动使用系统功能的系统命令,但我希望它立即返回,无论系统调用的结果。

I'm running a simple apache web server on Linux (Ubuntu 14.04) with a perl CGI script handling some requests. The script initiates a system command using the system function, but I want it to return immediately, regardless of the outcome of the system call.

我已经添加一个符号传递给系统标量参数的结尾(的我所知道的命令注入攻击的影响<中/ EM >),尽管这样做会导致系统命令立即返回,该脚本将仍然不会退出,直到底层的命令已完成。

I've been adding an ampersand to the end of the scalar argument passed to system (I am aware of the implications of command injection attacks) and although this does cause the system command to return immediately, the script will still not exit until the underlying command has completed.

如果我使用触发一个10秒的睡眠伪Ruby脚本将Perl CGI系统电话,然后我的请求发送到Web服务器仍然之前最后等待10秒得到的响应。我把日志语句系统电话后,它的网络请求时立即出现,因此系统通话肯定是立即返回,但脚本是在年底仍在等待。

If I trigger a dummy ruby script with a 10 second sleep using the system call from the perl CGI, then my request to the web server still waits 10 seconds before finally getting a response. I put a log statement after the system call and it appears immediately when the web request is made, so the system call is definitely returning immediately, but the script is still waiting at the end.

<一个href=\"http://stackoverflow.com/questions/22523543/how-do-i-make-a-system-call-and-resume-execution-without-waiting-for-the-call-to\">This问题是相似的,但无论是解决方案都为我工作。

This question is similar, but neither of the solutions have worked for me.

下面是一些例子code:

Here's some example code:

#!/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}';

编辑:结果
该命令调用使用执行须藤-u 因为Apache用户 www数据需要权限执行代表脚本剧本主人,我已经更新了我的sudoers文件适当实现这一目标。这不是我的问题的原因,因为我也试着改变剧本所有权 www数据运行系统(/ tmp / test目录.RB一二&安培;。),但结果是一样的。


The command call is executed using sudo -u because the apache user www-data needs permission to execute the script on behalf of the script owner, and I've updated my sudoers file appropriately to that end. This is not the cause of my issue, because I've also tried changing script ownership to www-data and running system("/tmp/test.rb one two &") but result is the same.

编辑2:结果
我也尝试添加 0退出到脚本的尽头,但它并没有任何区别。是否有可能脚本立即退出,但Apache服务器被抓着,直到脚本调用perl的CGI完成后的反应如何?或者是有可能的操作系统的某些设置或配置引起的问题?

Edit 2:
I've also tried adding exit 0 to the very end of the script, but it doesn't make any difference. Is it possible that the script is exiting immediately, but the apache server is holding onto the response until the script the perl CGI called is finished? Or is it possible that some setting or configuration of the operating system is causing the problem?

修改3:结果
直接从终端运行的Perl CGI脚本正常工作。 perl脚本立即结束,所以这不是用Perl固有的问题。其中presumably只能意味着Apache Web服务器被抓着,直到系统完成称为命令的请求。为什么呢?

Edit 3:
Running the perl CGI script directly from a terminal works correctly. The perl script ends immediately, so this is not an inherent issue with Perl. Which presumably can only mean that the Apache web server is holding onto the request until the command called from system is finished. Why?

推荐答案

Web服务器创建从中接收响应的管道。它等待的管在完成请求之前达到EOF。当作家手柄的所有副本都关闭的管道到达EOF。

The web server creates a pipe from which to receive the response. It waits for the the pipe to reach EOF before completing the request. A pipe reaches EOF when all copies of the writer handle are closed.

管道的作者尾设置为孩子的STDOUT。这个文件句柄复制是shell的标准输出,并再次向 mycmd 的STDOUT。因此,即使CGI脚本和外壳结束,从而关闭了他们的文件句柄的两端, mycmd 仍持有把手打开,让Web服务器仍在等待响应来完成的。

The writer end of the pipe is set as the child's STDOUT. That file handle was copied to be the shell's STDOUT, and again to the mycmd's STDOUT. So even though the CGI script and the shell ended and thus closed their ends of the file handle, mycmd still holds the handle open, so the web server is still waiting for the response to complete.

所有你有做关闭的最后一个手柄管的作家端。以上precisely,可以通过不同的手柄连接到 mycmd STDOUT避免它摆在首位。

All you have to do with to close the last handle to the writer end of the pipe. Or more precisely, you can avoid making it in the first place by attaching a different handle to mycmd STDOUT.

mycmd arg1 arg2 </dev/null >/dev/null 2>&1 &

这篇关于完perl脚本,而无需等待系统调用返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆