Proc::Daemon с mod_perl не записывает STDOUT или STDERR

Я использую Proc::Daemon в сценарии mod_perl таким образом:

$ bindir, $ ddir являются местоположениями исполняемого файла / файла журнала, а $jid является уникальным идентификатором для каждого процесса (во избежание открытия одного и того же файла несколькими процессами). $cmd загружается с произвольными сценариями Perl и аргументами.

   my $daemon = Proc::Daemon->new (
            work_dir        => $bindir,
            child_STDOUT    => $ddir.'/'.$jid.'_stdout.log',
            child_STDERR    => $ddir.'/'.$jid.'_stderr.log',
            pid_file        => $ddir.'/'.$jid.'_pid.txt',
            exec_command => $cmd,
    );

    my $pid = $daemon->Init();

Вышесказанное прекрасно работает при использовании Apache с cgi-script (без mod_perl). В процессе "$cmd" распечатайте и распечатайте журнал STDERR в указанных выше файлах журнала.

Когда я запускаю вышеупомянутое, используя mod_perl2, в Ubuntu Linux 14.04 LTS, используя Apache2, файл pid записывается с PID, и создаются вышеуказанные файлы журнала, но ничего не записывается в файлы журнала. Я могу открыть дескрипторы новых файлов в $ cmd и записать их, но в mod_perl он не отправляет выходные данные в файлы child_STDOUT и child_STDERR.

Я думаю, что мне не хватает чего-то действительно очевидного. Кто-нибудь еще видел это раньше, и / или есть какие-либо предложения, как заставить это работать в mod_perl.

Дополнительная информация Использование модуля mpm_prefork в Apache

Соответствующий Apache Config

    <Files "*.pl">
            # SetHandler cgi-script # It works if I use cgi-script
            SetHandler perl-script
            PerlOptions -SetupEnv # Tried with and without this
            # PerlHandler ModPerl::RegistryPrefork # Using this made no difference
            PerlHandler ModPerl::Registry

    </Files>

1 ответ

Итак, было так много решений, которые не работали. Это то, чем я занимался. Я создал скрипт с именем launchjob.pl:

#!/usr/bin/perl -w

use strict;
use warnings;

use POSIX 'setsid';
use Proc::Daemon;

my $bindir = $ARGV[0];
my $ddir = $ARGV[1];
my $jid = $ARGV[2];
my $cmd = $ARGV[3];

setsid or die "Cannot start a new session: $!";

my $daemon = Proc::Daemon->new (
                work_dir        => $bindir,
                child_STDOUT    => $ddir.'/'.$jid.'_stdout.log',
                child_STDERR    => $ddir.'/'.$jid.'_stderr.log',
                pid_file        => $ddir.'/'.$jid.'_pid.txt',
                exec_command => $cmd,
             );

my $pid = $daemon->Init();

exit 1;

Я заменил код в основной строке, где я вызывал Proc::Daemon, следующим текстом:

Следующее не сработало. Proc::Daemon дал мне sh: Нет такого файла или ошибки каталога.

system ('launchjob.pl', $ bindir, $ ddir, $ jid, $ cmd);

Вместо этого я использовал следующее, которое, кажется, работает как ожидалось.

использовать IPC::Run3; run3("launchjob.pl ".$bindir." ".$ddir." ".$jid." ".$cmd);

Это, кажется, исправило это прямо.

Другие вопросы по тегам