Perl:无法执行

时间:2012-08-06 14:12:27

标签: perl exec fork

我试图在不同平台上并行运行几个子进程。只有在各个平台上完成所有子进程后,父进程才应继续进行。

问题是,当我使用fork然后在子进程中运行'exec'命令时,它几乎立即结束。此外,输出不一致。几乎每次日志只显示一行。

-bash-2.05b$ cat Agent.SOLSPARC
caught SIGTERM signal, cleaning up

-bash-2.05b$ cat Agent.SOLSPARC
Host: EBSO9SPC  Login: esm2 

有时,几乎没有额外的行,最后消息“被信号15杀死”。我在'exec'中使用的命令实际上调​​用了一个脚本,该脚本连接到远程盒子并对它们运行make命令。出于测试目的,我目前只通过一个平台,即SOLSPARC。另外,我只想知道命令是否在任何给定平台上完成。

我不确定我是否正确地将所有参数传递给'exec',所以我尝试了不同的组合(在互联网上引用不同的链接后),但无济于事。一个重要的观察是,当我使用strace调试此问题时,该命令工作正常。我在perldoc中看到exec在Unix平台上使用 / bin / sh -c ,但在其他平台上有所不同。是exec和strace使用不同的shell吗?

这是我的代码的相关部分:

sub compile {
    my %child_pids;
    foreach $plat (0 .. $#plat_list) {
        my $pid = fork;
        # Didn't check the undef condition for child
        if ($plat_list[$plat] eq "SOLSPARC") {
            print "\nStarted Solaris build \n";
            if ($pid == 0) {
                print "Inside Child Process \n\n";
                exec ( "${ROOT}/${REM_EXEC} -t 1200 -c \"make LANG=en_US distclean \" -b ${ROOT} -l Agent. $plat_list[$plat]" ) or die "exec failed";
            } elsif ($pid > 0) {
                $child_pids{"SOLSPARC"} = $pid;
            }
        } else {
           print "\nStarted build for other platforms \n";
           if ($pid == 0) {
                print "Inside Child Process \n\n";
                exec ( "${ROOT}/${REM_EXEC} -t 1200 -c \"make LANG=en_GB clean \" -b ${ROOT} -l Agent. $plat_list[$plat]" ) or die "exec failed";     
           } elsif ($pid > 0) {
                $child_pids{"$plat_list[$plat]"} = $pid;
           }
        }
    }


    my %rev_child_pids = reverse %child_pids;
    while ((my $kid = waitpid -1, WNOHANG) > 0) {
        if ($rev_child_pids{$kid} eq "SOLSPARC") {
            print "\nChild process completed for SOLARIS platform $rev_child_pids{$kid} \n";
            print "Run some other command here \n";
        } else {
            print "\nChild process completed for other platform $rev_child_pids{$kid} \n";
            print "No more commands to run \n";
        }
    }
}

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

尝试使用'system'而不是'exec'。

system `${ROOT}/${REM_EXEC} -t 1200 -c "make LANG=en_US distclean " -b ${ROOT} -l Agent. $plat_list[$plat]` 

'system'与fork的工作方式略有不同,因此可以解决问题。