我有一个漫长的运行过程,我需要它来启动另一个进程(也将运行一段时间)。我只需要启动它,然后完全忘掉它。

我设法通过从编程Ruby书中搜索一些代码来做我需要的东西,但我想找到最佳/正确的方法,并了解正在发生的事情。这是我最初得到的:

exec("whatever --take-very-long") if fork.nil?
Process.detach($)

结果

那么,这是方式,还是我应该怎么办?

在检查下面的答案后,我最终得到了这段代码,这似乎更有意义:

(pid = fork) ? Process.detach(pid) : exec("foo")

结果

我很欣赏有关 fork 如何工作的一些解释。 [已经得到了]

正在分离 $$ 吗?我不知道为什么会这样,我真的很想更好地掌握这种情况。

有帮助吗?

解决方案

fork 函数将您的进程分成两部分。

然后

两个进程都会收到函数的结果。子元素的值为零/ nil (因此知道它是子元素),父元素接收子元素的PID。

因此:

exec("something") if fork.nil?

将使子进程启动“some”,并且父进程将继续进行。

请注意, exec() 使用“something”替换当前进程,因此子进程永远不会执行任何后续的Ruby代码。

Process.detach()的调用看起来可能不正确。我原以为它会让孩子的PID在其中,但是如果我正确读取你的代码,它实际上是在分离父进程。

其他提示

Alnitak是对的。这是一种更明确的编写方式,没有$$

pid = Process.fork
if pid.nil? then
  # In child
  exec "whatever --take-very-long"
else
  # In parent
  Process.detach(pid)
end

分离的目的只是说,“当孩子终止时我不在乎”。避免僵尸进程

分离 $$ 是不对的。从p。 Pickaxe(第二版)中的348个:

  

$$ Fixnum正在执行的程序的进程号。 [r / o]

本节“变量和常数”在“Ruby语言”中章,对于解码各种ruby短 $ 常量非常方便 - 不过在线版(第一个

所以你实际上在做的是将程序与自己分开,而不是从它的孩子那里分离出来。 像其他人所说的那样,与孩子分离的正确方法是使用从 fork()返回的孩子的pid。

如果您确定要分离子进程,其他答案都很好。但是,如果您不介意,或者希望保持附加子进程(例如,您正在为Web应用程序启动子服务器/服务),那么您可以利用以下简写

fork do
    exec('whatever --option-flag')
end

提供一个块告诉fork在子进程中执行该块(并且只有那个块),同时在父进程中继续。

我发现上面的答案打破了我的终端并弄乱了输出。这是我找到的解决方案。

   system("nohup ./test.sh &")

万一有人遇到同样的问题,我的目标是登录ssh服务器,然后让该进程无限期地运行。所以test.sh就是这个

#!/usr/bin/expect -f
spawn ssh host -l admin -i cloudkey  
expect "pass"
send "superpass\r"
sleep 1000000
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top