Running windows cmd using ruby rake - ruby

I'm trying to run some windows command line calls in the same system
process using a Ruby Rake task. I need to find the way to do the calls
correctly and this calls can't be dependent on each other.
I know that the 'fork' function can be a solution, but it doesn't work
in Windows. I tried with other functions, like IO.POPEN and
Process.spawn and I didn't find a real solution.
I'm working with Ruby 1.9.3 in windows XP.
task :CmdTest,:value do |t, args|
value=args.value.to_s
begin
$cmd<<("set MYVAR=#{value}")
$cmd<<("set MYVAR")
$cmd<<("exit")
rescue Exception => e
puts e.message
end
end
task :CmdTest3 do
IO.popen("cmd", "r+") do |io|
th = Thread.new(io) do |chan|
chan.each {|line| puts line}
end
$cmd.each do |f|
io.puts f
end
io.close_write
th.join
end
end

Take a look at win32utils, is that what you are after?

Related

Windows - Execute ruby functions in separate process

I'm trying to execute Ruby functions in separate processes on my Windows system. On Mac, I used the Fork method. But that doesn't work on Windows. I also tried the spawn method. But that doesn't seem to work either.
def test_1
puts "Hello"
end
def test_2
puts " World"
end
On Mac (Works)
pid_1 = Fork.do
test_1
end
pid_2 = Fork.do
test_2
end
Process.waitall
On Windows (Doesn't work)
pid_1 = Process.spawn(test_1)
pid_2 = Process.spawn(test_2)
Process.waitall
Exception: NoMethodError - undefined method `spawn' for Process:Module
Ruby version: 2.0
Can someone help me in understanding what I'm missing.
Edit: Found the issue. The Ruby version was old (1.8.7) which doesn't implement this method.

Can I determine if Ruby code is executing in a Sidekiq job?

Can I do something like the following? If yes, how do I implement in_sidekiq_job?
def method_for_anyone_to_call
if in_sidekiq_job
puts "hey! I'm running in a Sidekiq job."
end
end
You can use Sidekiq.server? for that, i.e.:
def method_for_anyone_to_call
if Sidekiq.server?
puts "hey! I'm running in a Sidekiq job."
end
end

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?
i.e 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

How to read and process a file in Ruby with EventMachine

I am wondering if anybody figured out a way to process bigger (500Mb+) text files with EventMachine, where you actually need to access the individual lines.
I guess I found the answer, the only thing is messy is the read_chunk gets called in the after io.gets, and I am not sure why it works :)
require 'eventmachine'
def process_line(line)
puts line
end
EM.run do
io = File.open('query_profiles.csv')
read_chunk = proc do
if line = io.gets
process_line(line)
EM.next_tick(read_chunk)
else
EM.stop
end
end
EM.next_tick(read_chunk)
end

In rake task, execute command, read stdout until a certain line is matched, then detach and continue task

I want to launch a java servlet, observe its stdout until I see that it has fully loaded, and then go back to the rest of my rake task while keeping that process running. Currently I have something like this:
IO.popen "java -jar ./tools/tests/servlet.jar" do |io|
io.each do |line|
puts line
Process.detach(io.pid) if line.include? 'Server ready.' # need help here
end
end
puts "Ready..."
How do I exit this IO block to continue with the task, while keeping the process running? Thank you!
Edit: Temporary Bad Solution
def with_server_running
IO.popen "java -jar ./tools/tests/servlet.jar" do |io|
io.each do |line|
puts line
yield if line.include? 'Server ready.'
end
end
end
with_server_running do
puts "Ready..."
# rest of task
end
If I understand you correctly, try this:
if(line.include? 'Server ready.')
Process.detach(io.pid)
exit(0)
end

Resources