从ruby脚本运行另一个ruby脚本

And*_*imm 35 ruby

在ruby中,是否可以指定使用相同的ruby解释器调用另一个ruby脚本,因为原始脚本正在运行?

例如,如果a.rb运行b.rb几次,是否可以替换

system("ruby", "b.rb", "foo", "bar")
Run Code Online (Sandbox Code Playgroud)

喜欢的东西

run_ruby("b.rb", "foo", "bar")
Run Code Online (Sandbox Code Playgroud)

所以,如果你ruby1.9.1 a.rb在原版ruby1.9.1上使用,将在b.rb上使用,但如果你刚用于ruby a.rb原版,ruby将用于b.rb?

我不想使用shebangs,因为我希望能够在不同的计算机上运行,​​其中一些计算机没有/usr/bin/env.

编辑:我没有意思loadrequire类似,但产生新的进程(所以我可以使用多个CPU).

Mat*_*hen 22

require "b.rb"
Run Code Online (Sandbox Code Playgroud)

将执行b.rb的内容(你打电话给".rb",并有一个搜索路径).在您的情况下,您可能会执行以下操作:

a.rb:

require "b.rb";
b("Hello", "world")
Run Code Online (Sandbox Code Playgroud)

b.rb:

def b(first, second)
  puts first + ", " + second
end
Run Code Online (Sandbox Code Playgroud)

请注意,如果使用require,Ruby将只加载并执行一次文件(每次调用load时都会重新加载),但您可以根据需要多次调用文件中定义的方法.

随着事情变得越来越复杂,您将希望转向面向对象的设计.

编辑:在这种情况下,你应该看看Ruby线程.一个简单的例子是:

a.rb:

require "b";
t1 = Thread.new{b("Hello", "world");}
t2 = Thread.new{b("Hello", "galaxy");}
t1.join
t2.join
Run Code Online (Sandbox Code Playgroud)

b.rb:

def b(first, second)
  10.times {
    puts first + ", " + second;
    sleep(0.1);
  }
end
Run Code Online (Sandbox Code Playgroud)


Jör*_*tag 11

Avdi GrimmDevver博客上写了一系列关于去年夏天启动Ruby子进程的不同方法的文章:

[注意:似乎第4部分尚未发布.]

  • 这个问题有一个简单的命令答案吗? (3认同)
  • 这不是答案 (3认同)

小智 7

需要技巧是一个好主意,假设有问题的脚本没有阻止尝试重新定义您可能已经设置的任何常量,或者调用对象上的方法,您可能已经修改了运行时猴子以不再遵守其标准合同.

在任何一种情况下,问题都不是方法,而是脚本本身的代码.显示良好的方式,将常量放在命名空间中,并且不要破坏性地修补运行时.

要确保有问题的脚本不会破坏调用脚本的运行时,并防止它可能在某处调用Kernel/Process.exit(),请尝试以下操作

pid=Process.fork do
    require 'script.rb'
    Process.exit
end
ignored, status = Process.waitpid2(pid, Process::WNOHANG)
puts "script.rb PID #{pid} exited, exit status: #{status.exitstatus}" 
Run Code Online (Sandbox Code Playgroud)

对于更高级的事情,比如写入stdin流或从stdout或stderr流中读取,请使用Open4 gem.


Jak*_*ner 6

如果您只想在现有进程的上下文中运行脚本,您也可以这样做

eval File.read("/path/to/your/script.rb")
Run Code Online (Sandbox Code Playgroud)

不确定您的用例是什么,但这可能很有用,例如,如果您打开了一个 Rails 控制台并且您想在临时文件中执行一些代码,但又不想一直将整个代码块复制到您的安慰。