远程运行时perl fork无法正常工作(通过ssh)

Raz*_*orm 5 unix ssh perl fork

我有一个perl脚本,script.pl,当运行时,它执行一个fork,父进程将其pid输出到一个文件,然后在子进程输出某些东西到STOUT然后进入while循环时退出.

$pid = fork();

if ( ! defined $pid ) 
{
    die "Failed to fork.";
}
#Parent process
elsif($pid)
{
    if(!open (PID, ">>running_PIDs"))
    {
        warn "Error opening file to append PID";
    }
    print PID "$pid  \n";
    close PID;
}
#child process
else
{
    print "Output started";

    while($loopControl)     
    {
           #Do some stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在本地调用它时,这工作正常,即:perl script.pl.

该脚本打印出一些东西,然后将控制权返回给shell.(当子进程在后台进入循环时).

但是,当我通过ssh调用它时,控件永远不会返回到shell(也不会打印出"Output started"行).

ie:$ ssh username@example.com'perl script.pl'

然而,有趣的是,子进程确实运行(当我输入ps时我可以看到它).

任何人都可以解释发生了什么?

编辑:

我在调试下运行它得到了这个:

###分叉,但不知道如何创建新的TTY.

由于两个调试器争用相同的TTY,输入严重纠缠.

我知道如何仅在xterms和OS/2控制台中将输出切换到不同的窗口.对于手动切换,将创建的TTY的名称放在$ DB :: fork_TTY中,或者定义一个返回此功能的DB :: get_fork_TTY()函数.

在类UNIX系统上,可以通过键入tty获取给定窗口的TTY名称,并通过sleep 1000000将shell与TTY断开连接.

pra*_*pra 9

每当您通过非交互式ssh命令启动后台作业时,您需要关闭或以其他方式绑定stdin,stdout和stderr.否则ssh将等待后台进程退出. FAQ.

这称为取消与控制终端的关联或分离,是编写后台作业时的一般最佳实践,而不仅仅是SSH.

因此,最简单的更改不会使整个命令静音是添加:

#close std fds inherited from parent
close STDIN;
close STDOUT;
close STDERR;
Run Code Online (Sandbox Code Playgroud)

就在你之后print "Output started";.如果您的子进程需要在运行期间定期打印输出,那么您需要重定向到日志文件.