Net::OpenSSH - search.cpan.org のドキュメントでは、Net::OpenSSH->new(async => 1) や $ssh->spawn() が使えそうにも思えましたが、結局、nohup 〜 & に落ち着きました。
cgi(mod_perl)環境による影響でしょうか?
※「nohup $cmd >/dev/null 2>/dev/null http://www.codereading.com/nb/ignore-the-hangup-signal.html
package EanUtil::BulkMail; use strict; use utf8; use base qw/EanUtil/; use Encode; use EanUtil::Config; use JSON; use Net::OpenSSH; use Data::Dumper; my $CONF = EanUtil::Config->get_config(); sub new { my ($class) = @_; my $self = {}; return bless $self, $class; } sub act_main { my ( $self, $q ) = @_; my $action = $q->param('action') || ''; if ( $action eq "set_mailto_list" or #配信対象者の抽出 $action eq "send_bulk_mail" #メール送信実行(バックグラウンド実行) ){ my $method = "act_$action"; return $self->$method($q); } die "unknown action=$action $!"; } #メール送信実行 sub act_send_bulk_mail { my ( $self, $q ) = @_; my ($ssh,$msg_tmp) = $self->connect_ssh(); unless($ssh){ my $ret = {}; $ret->{result} = undef; $ret->{msg} = join(' ','SSH接続に失敗しました.',$msg_tmp); $self->response_json($ret); return undef; } my $mail_type = $q->param('mail_type'); ## backgroundで実行 ##refer to http://www.codereading.com/nb/ignore-the-hangup-signal.html my $ssh_cmd = join('', "nohup ", "$CONF->{bulk_mail}->{php} ", "$CONF->{bulk_mail}->{ean_app_root}/batch/", "$BULK_CMDS->{$mail_type}->{send_bulk_mail} ", " >/dev/null 2>/dev/null </dev/null &"); unless( $ssh->system($ssh_cmd) ){ my $err_msg = $ssh->error .$ssh_cmd; my $ret = {}; $ret->{result} = undef; $ret->{msg} = join(' ','SSH実行に失敗しました.',$err_msg); $self->response_json($ret); return undef; } my $ret = {}; $ret->{result} = 'success'; $self->response_json($ret); return $self; } #メール送信先の登録 sub act_set_mailto_list { my ( $self, $q ) = @_; my ($ssh,$msg_tmp) = $self->connect_ssh(); unless($ssh){ my $ret = {}; $ret->{result} = undef; $ret->{msg} = join(' ','SSH接続に失敗しました.',$msg_tmp); $self->response_json($ret); return undef; } my $mail_type = $q->param('mail_type'); my $ssh_cmd = join('', $CONF->{bulk_mail}->{php}, ' ', "$CONF->{bulk_mail}->{ean_app_root}/batch/", "$BULK_CMDS->{$mail_type}->{set_mailto_list}"); unless( $ssh->system($ssh_cmd) ){ my $err_msg = $ssh->error .$ssh_cmd; my $ret = {}; $ret->{result} = undef; $ret->{msg} = join(' ','SSH実行に失敗しました.',$err_msg); $self->response_json($ret); return undef; } my $ret = {}; $ret->{result} = 'success'; $self->response_json($ret); return $self; } sub connect_ssh { my ($self) = @_; my $DUMMY_STDIN_OUT = '/dev/null'; open(my $stdin_fh, $DUMMY_STDIN_OUT) or die "can't open $DUMMY_STDIN_OUT $!"; open(my $stdout_fh,$DUMMY_STDIN_OUT) or die "can't open $DUMMY_STDIN_OUT $!"; my $option = {default_stdin_fh => $stdin_fh, default_stdout_fh => $stdin_fh}; my $ssh = Net::OpenSSH->new($CONF->{bulk_mail}->{ssh_host}, user =>$CONF->{bulk_mail}->{ssh_user}, password=>$CONF->{bulk_mail}->{ssh_passwd}, %$option); if($ssh->error){ my $msg = join(' ', "fail ssh to", "host:$CONF->{bulk_mail}->{ssh_host}", "user:$CONF->{bulk_mail}->{ssh_user}", $ssh->error); return undef, $msg; } return $ssh; } sub response_json { my ($self,$res) = @_; print CGI::header(-type=>'text/plain',-charset=>'UTF-8'); print encode_utf8(JSON::to_json($res||{})); } 1; __END__