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断开连接.
每当您通过非交互式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";.如果您的子进程需要在运行期间定期打印输出,那么您需要重定向到日志文件.