Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Получить вывод ошибок из другого процесса


Автор: artem78 15.5.2015, 18:54
Как можно получить вывод STDERR процесса sendmail в переменную? Решение нужно для Windows.

Код

    sub send_by_sendmail {
        my $self = shift;
        my $return;
        if ( @_ == 1 and !ref $_[0] ) {
            ### Use the given command...
            my $sendmailcmd = shift @_;
            Carp::croak "No sendmail command available" unless $sendmailcmd;
    
            ### Do it:
            local *SENDMAIL;
            open SENDMAIL, "|$sendmailcmd" or Carp::croak "open |$sendmailcmd: $!\n";
            $self->print( \*SENDMAIL );
            close SENDMAIL;
            $return = ( ( $? >> 8 ) ? undef: 1 );
        } else {    ### Build the command...
            my %p = $self->_unfold_stupid_params(@_);
    
            $p{Sendmail} = $SENDMAIL unless defined $p{Sendmail};
    
            ### Start with the command and basic args:
            my @cmd = ( $p{Sendmail}, @{ $p{BaseArgs} || [ '-t', '-oi', '-oem' ] } );
    
            # SetSender default is true
            $p{SetSender} = 1 unless defined $p{SetSender};
    
            ### See if we are forcibly setting the sender:
            $p{SetSender} ||= defined( $p{FromSender} );
    
            ### Add the -f argument, unless we're explicitly told NOT to:
            if ( $p{SetSender} ) {
                my $from = $p{FromSender} || ( $self->get('From') )[0];
                if ($from) {
                    my ($from_addr) = extract_full_addrs($from);
                    push @cmd, "-f$from_addr" if $from_addr;
                }
            }
    
            ### Open the command in a taint-safe fashion:
            my $pid = open SENDMAIL, "|-";
            defined($pid) or die "open of pipe failed: $!\n";
            if ( !$pid ) {    ### child
                exec(@cmd) or die "can't exec $p{Sendmail}: $!\n";
                ### NOTREACHED
            } else {          ### parent
                $self->print( \*SENDMAIL );
                close SENDMAIL || die "error closing $p{Sendmail}: $! (exit $?)\n";
                $return = 1;
            }
        }
        return $self->{last_send_successful} = $return;
    }

Автор: arto 16.5.2015, 11:15
perldoc IPC::Run3 IPC::Run ?

Автор: artem78 16.5.2015, 14:49
Если сделать вот так, процесс намертво виснет.

Код
local (*WRITER, *READER, *ERROR);
my $pid = open3(\*WRITER, \*READER, \*ERROR, $sendmailcmd);
$self->print( \*WRITER ); # Отправка письма sendmail-у

my $errors = '';
while (my $errout = <ERROR>) {
    $errors .= $errout;
}

waitpid( $pid, 0 ) or die "$!\n";
if ($? >> 8) {
    $return = undef;
    #
    # делаю что-нибудь с переменной $errors ...
    #
} else {
    $return = 1;
}

Автор: arto 17.5.2015, 14:07
что именно вы хотели сделать этим кодом?

Автор: Loki 6.6.2015, 13:54
попробуй IO::Capture::Stderr
иил вот так в файл

open(STDERR,">/tmp/err.log"); 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)