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

时间:2022-06-27 16:20:51

In ruby, is it possible to specify to call another ruby script using the same ruby interpreter as the original script is being run by?

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

For example, if a.rb runs b.rb a couple of times, is it possible to replace

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

system("ruby", "b.rb", "foo", "bar")

with something like

有类似的东西

run_ruby("b.rb", "foo", "bar")

so that if you used ruby1.9.1 a.rb on the original, ruby1.9.1 would be used on b.rb, but if you just used ruby a.rb on the original, ruby would be used on b.rb?

所以,如果你在原版上使用ruby1.9.1 a.rb,ruby1.9.1将在b.rb上使用,但如果你只在原版上使用ruby a.rb,那么ruby会在b.rb上使用吗?

I'd prefer not to use shebangs, as I'd like it to be able to run on different computers, some of which don't have /usr/bin/env.

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

Edit: I didn't mean load or require and the like, but spawning new processes (so I can use multiple CPUs).

编辑:我不是指加载或需要等,而是产生新的进程(所以我可以使用多个CPU)。

7 个解决方案

#1


10  

Avdi Grimm wrote a series of articles on the Devver blog about different ways to start Ruby subprocesses last summer:

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

[Note: it appears that part 4 hasn't been published yet.]

[注意:看来第4部分尚未发布。]

#2


21  

require "b.rb"

will execute the contents of b.rb (you call leave off the ".rb", and there is a search path). In your case, you would probably do something like:

将执行b.rb的内容(你打电话给“.rb”,并有一个搜索路径)。在你的情况下,你可能会做这样的事情:

a.rb:

a.rb:

require "b.rb";
b("Hello", "world")

b.rb:

b.rb:

def b(first, second)
  puts first + ", " + second
end

Note that if you use require, Ruby will only load and execute the file once (every time you call load it will be reloaded), but you can call methods defined in the file as many times as you want.

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

As things get more complex, you will want to move towards an object-oriented design.

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

EDIT: In that case, you should look into Ruby threading. A simple example is:

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

a.rb:

a.rb:

require "b";
t1 = Thread.new{b("Hello", "world");}
t2 = Thread.new{b("Hello", "galaxy");}
t1.join
t2.join

b.rb:

b.rb:

def b(first, second)
  10.times {
    puts first + ", " + second;
    sleep(0.1);
  }
end

#3


7  

The require trick is a good idea, assuming the script in question doesn't choke trying to redefine any constants you may have set, or calling methods on objects you may have runtime monkey patched to no longer honor their standard contracts.

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

In either case, the problem is less the approach than it is the code in the scripts themselves. Show good manners, put your constants in a namespace, and don't monkey patch the runtime desctructively.

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

To ensure the script in question doesn't mess with the runtime of your calling script, and to guard against the chance it might call Kernel/Process.exit() somewhere, try the following

要确保有问题的脚本不会破坏调用脚本的运行时,并防止它可能在某处调用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}" 

For more advanced things like writing to its stdin stream or reading from its stdout or stderr streams, use the Open4 gem.

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

#4


2  

If you just want to run a script in the context of an existing process, you can also do this

如果您只想在现有流程的上下文中运行脚本,也可以执行此操作

eval File.read("/path/to/your/script.rb")

Not sure what your use case is but this could be useful for example if you have a Rails console open and you want to execute some code in a scratch file, but don't want to have to keep copying the entire block of code into your console.

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

#5


1  

http://en.wikibooks.org/wiki/Ruby_Programming/Running_Multiple_Processes might help

http://en.wikibooks.org/wiki/Ruby_Programming/Running_Multiple_Processes可能会有所帮助

#6


1  

This is what I have used

这是我用过的

/myapp/script/main_script.rb


load rails env, only if you need to

ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")

run other slave scripts from within main_script.rb

从main_script.rb中运行其他从属脚本

require File.expand_path(File.dirname(__FILE__) + "/../script/populate_wh_grape_varieties_table.rb")

#7


0  

Charles Nutter, of JRuby fame, is suggesting a Kernel#ruby method to call a Ruby script using the same Ruby implementation as you're currently using.

JRuby成名的Charles Nutter建议使用内核#ruby方法来调用Ruby脚本,使用与您当前使用的相同的Ruby实现。

Edit: the proposal was rejected. Matz said that MVM (multiple virtual machines) may provide the solution.

编辑:提案被拒绝。 Matz说MVM(多个虚拟机)可能提供解决方案。

#1


10  

Avdi Grimm wrote a series of articles on the Devver blog about different ways to start Ruby subprocesses last summer:

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

[Note: it appears that part 4 hasn't been published yet.]

[注意:看来第4部分尚未发布。]

#2


21  

require "b.rb"

will execute the contents of b.rb (you call leave off the ".rb", and there is a search path). In your case, you would probably do something like:

将执行b.rb的内容(你打电话给“.rb”,并有一个搜索路径)。在你的情况下,你可能会做这样的事情:

a.rb:

a.rb:

require "b.rb";
b("Hello", "world")

b.rb:

b.rb:

def b(first, second)
  puts first + ", " + second
end

Note that if you use require, Ruby will only load and execute the file once (every time you call load it will be reloaded), but you can call methods defined in the file as many times as you want.

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

As things get more complex, you will want to move towards an object-oriented design.

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

EDIT: In that case, you should look into Ruby threading. A simple example is:

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

a.rb:

a.rb:

require "b";
t1 = Thread.new{b("Hello", "world");}
t2 = Thread.new{b("Hello", "galaxy");}
t1.join
t2.join

b.rb:

b.rb:

def b(first, second)
  10.times {
    puts first + ", " + second;
    sleep(0.1);
  }
end

#3


7  

The require trick is a good idea, assuming the script in question doesn't choke trying to redefine any constants you may have set, or calling methods on objects you may have runtime monkey patched to no longer honor their standard contracts.

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

In either case, the problem is less the approach than it is the code in the scripts themselves. Show good manners, put your constants in a namespace, and don't monkey patch the runtime desctructively.

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

To ensure the script in question doesn't mess with the runtime of your calling script, and to guard against the chance it might call Kernel/Process.exit() somewhere, try the following

要确保有问题的脚本不会破坏调用脚本的运行时,并防止它可能在某处调用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}" 

For more advanced things like writing to its stdin stream or reading from its stdout or stderr streams, use the Open4 gem.

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

#4


2  

If you just want to run a script in the context of an existing process, you can also do this

如果您只想在现有流程的上下文中运行脚本,也可以执行此操作

eval File.read("/path/to/your/script.rb")

Not sure what your use case is but this could be useful for example if you have a Rails console open and you want to execute some code in a scratch file, but don't want to have to keep copying the entire block of code into your console.

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

#5


1  

http://en.wikibooks.org/wiki/Ruby_Programming/Running_Multiple_Processes might help

http://en.wikibooks.org/wiki/Ruby_Programming/Running_Multiple_Processes可能会有所帮助

#6


1  

This is what I have used

这是我用过的

/myapp/script/main_script.rb


load rails env, only if you need to

ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")

run other slave scripts from within main_script.rb

从main_script.rb中运行其他从属脚本

require File.expand_path(File.dirname(__FILE__) + "/../script/populate_wh_grape_varieties_table.rb")

#7


0  

Charles Nutter, of JRuby fame, is suggesting a Kernel#ruby method to call a Ruby script using the same Ruby implementation as you're currently using.

JRuby成名的Charles Nutter建议使用内核#ruby方法来调用Ruby脚本,使用与您当前使用的相同的Ruby实现。

Edit: the proposal was rejected. Matz said that MVM (multiple virtual machines) may provide the solution.

编辑:提案被拒绝。 Matz说MVM(多个虚拟机)可能提供解决方案。