perl fork不';远程运行时无法正常工作(通过ssh)
我有一个perl脚本,script.pl,它在运行时执行fork,父进程将其pid输出到一个文件,然后退出,而子进程输出要执行的内容,然后进入while循环perl fork不';远程运行时无法正常工作(通过ssh),perl,unix,ssh,fork,Perl,Unix,Ssh,Fork,我有一个perl脚本,script.pl,它在运行时执行fork,父进程将其pid输出到一个文件,然后退出,而子进程输出要执行的内容,然后进入while循环 $pid = fork(); if ( ! defined $pid ) { die "Failed to fork."; } #Parent process elsif($pid) { if(!open (PID, ">>running_PIDs")) { warn "Error o
$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
}
}
当我在本地调用它(即:perlscript.pl)时,它工作得很好
脚本打印出一些内容,然后将控制权返回shell。(当子进程在后台进入循环时)
但是,当我通过ssh调用时,控制永远不会返回到shell(也不会打印“Output start”行)
即:
$sshusername@example.com“perl script.pl”
然而,有趣的是,子进程确实在运行(当我键入ps时可以看到它)
有人能解释发生了什么事吗
编辑:
我在debug下运行了它,得到了以下结果:
###分叉,但不知道如何创建新的TTY。
由于两个调试器争夺同一个TTY,因此输入严重纠缠
我知道如何在xterms中将输出切换到其他窗口
仅限OS/2控制台。对于手动开关,请输入创建的TTY的名称
在$DB::fork\u TTY中,或定义一个函数DB::get\u fork\u TTY()返回此值
在类UNIX系统上,可以获得给定窗口的TTY名称
通过键入tty,并通过sleep 1000000断开shell与tty的连接。
sshusername@example.com“nohup perl script.pl”
您无法退出,因为仍然连接了一个进程。您需要
nohup
它。发生的情况是ssh正在直接以命令的形式执行“perl script.pl”。如果您有可用的“screen”,您可以执行以下操作:
$ ssh username@example.com 'screen -d -m perl script.pl'
要使其在分离的屏幕上运行,并在以后通过非交互式ssh命令启动后台作业时使用screen-r重新连接,需要关闭或以其他方式绑定stdin、stdout和stderr。否则,ssh将等待后台进程退出 这称为与控制终端解除关联或分离,是编写后台作业时的一般最佳实践,而不仅仅是针对SSH 因此,不使整个命令静音的最简单更改是添加:
#close std fds inherited from parent
close STDIN;
close STDOUT;
close STDERR;
就在您的
打印“输出已启动”;
之后。如果您的子进程在运行期间需要定期打印输出,则您需要重定向到日志文件。为了更好地理解这一点,我建议您在上阅读@Jax的解决方案
这与Perl无关,这是因为SSH处理任何试图在后台运行的长时间进程的方式
我需要从bash脚本启动script.pl(在目标主机上定义基本的局部变量):
/path/to/launcher.sh使用以下命令调用Perl脚本:
CMD="/path/to/script.pl -some_arg=$VALUE -other_arg"
$CMD &
它在本地工作,但通过ssh运行时没有返回
我在Perl脚本中尝试了@pra的解决方案,但在我的例子中没有成功
使用@Jax的解决方案,我用以下内容替换了$CMD&
:
nohup $CMD > /path/to/output.log 2>&1 < /dev/null &
nohup$CMD>/path/to/output.log 2>&1
它工作得很好。这可以工作,返回控制。通过ssh远程运行它与本地运行它有什么不同?当它是本地运行时,它没有问题吗?@Razor,远程运行时,没有shell——另一端的ssh守护进程运行并将自身连接到脚本。您可能还可以实现您可以在ssh命令下运行
bash-c“perl script.pl”
,但是,父进程结束了,所以附加的守护进程不也应该停止运行吗?似乎没有任何效果。=[如果有人对这个问题有解决方案,而不是screen
(我并不总是有可用的解决方案),我很想看。在阅读您的帖子之前,浪费了几个小时进行调试。谢谢,它很管用!
nohup $CMD > /path/to/output.log 2>&1 < /dev/null &