简体   繁体   中英

A ruby script to run other ruby scripts

If I want to run a bunch of ruby scripts (super similar, with maybe a number changed as a commandline argument) and still have them output to stdout, is there a way to do this?

ie a script to run these:

               ruby program1.rb input_1.txt
               ruby program1.rb input_2.txt
               ruby program1.rb input_3.txt

like

 (1..3).each do |i|
    ruby program1.rb input_#{i}'
 end

in another script, so I can just run that script and see the output in a terminal from all 3 runs?

EDIT:

I'm struggling to implement the second highest voted suggested answer.

I don't have a main function within my program1.rb, whereas the suggested answer has one.

I've tried this, for script.rb:

require "program1.rb"
(1..6).each do |i|
    driver("cmd_line_arg_#{i}","cmd_line_arg2")
end

but no luck. Is that right?

You can use load to run the script you need (the difference between load and require is that require will not run the script again if it has already been loaded).

To make each run have different arguments (given that they are read from the ARGV variable), you need to override the ARGV variable:

(1..6).each do |i|
  ARGV = ["cmd_line_arg_#{i}","cmd_line_arg2"]
  load 'program1.rb'
end
# script_runner.rb

require_relative 'program_1'

module ScriptRunner
  class << self
    def run
      ARGV.each do | file |
        SomeClass.new(file).process
      end
    end
  end
end

ScriptRunner.run

.

# programe_1.rb

class SomeClass

  attr_reader :file_path

  def initialize(file_path)
    @file_path = file_path
  end

  def process
    puts File.open(file_path).read
  end
end

Doing something like the code shown above would allow you to run:

ruby script_runner.rb input_1.txt input_2.txt input_3.txt

from the command line - useful if your input files change. Or even:

ruby script_runner.rb *.txt

if you want to run it on all text files. Or:

ruby script_runner.rb inputs/*

if you want to run it on all files in a specific dir (in this case called 'inputs').

This assumes whatever is in program_1.rb is not just a block of procedural code and instead provides some object (class) that encapsulates the logic you want to use on each file,meaning you can require program_1.rb once and then use the object it provides as many times as you like, otherwise you'll need to use #load:

# script_runner.rb

module ScriptRunner
  class << self
    def run

      ARGV.each do | file |
        load('program_1.rb', file)
      end
    end
  end
end

ScriptRunner.run

.

# program_1.rb

puts File.open(ARGV[0]).read

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM