Ruby: how to use Process.spawn to run Ruby code - ruby

For some reasons, I need to use Ruby Process.spawn to run a Ruby lambda. It seems that Process.spawn takes a string for shell command.
task = lambda do
work()
otherJobs()
end
Process.spawn(task) # TypeError: no implicit conversion of Proc into String
I wonder how to run Ruby code with Process.spawn.

Related

How to store rake task call result in shell?

I am newbie in Ruby, Rake and shell script. Here I created one simple task in Rake which parse YAML file and returns its response.
Following is the task in my Rakefile. It works fine and puts prints the yaml value on console.
task :test, [:env] do |t, args|
db_settings = YAML::load(File.open("test.yml"))["#{args[:env]}"]
puts db_settings
end
Following is the result of the task.
{"url"=>"http://test.com", "end"=>"test"}
["test[local]"]
But when I want to call this task from shell script then it didn't return response to script.
not sure ruby not able to send response or script itself doing something wrong.
Following is shell script that I am using to call this rake task.
res= rake test[local]
echo $res
How can I get this parsed yaml from rake task to shell script?
Second question is, will this script be able to use this Parsed yaml. Rake task returns env specific json structure to script and the script supposed to get the element using key.
Can someone help on this to? is the current approach to use Yaml on script.

using SCL in the command call for Ruby script

My employer has Ruby 1.8.7 in the /usr/bin/ruby, and allows the usage of Ruby 2.4 only via SCL (sofoware collections).
Which means that when I run ruby, I need to use (from the RH6 shell) scl enablde ruby-24 'ruby foo.rb' when foo.rb
is the file name.
I want to enable the ruby call on the first execution line, i.e., instead of the Ruby code file looking like:
#!/usr/bin/ruby
puts "Hello world"
That the code will look
#!cmd
puts "Hello world"
Where the cmd is what calls via the scl and run the Ruby 2.4 for the puts command. I know that a wrapper file can be used. I want something in 1 file.
How about this:
#!/usr/bin/ruby
if RUBY_VERSION != "2.4.1"
exec "scl enable ruby-24; ruby __FILE__"
end
puts "Ruby Version: #{RUBY_VERSION}"

puppet run ruby script with execute shell command and variable not working.

my code
cmd_result = %x("#{rndc}" "#{cmd_arg}" "#{zone}" in "#{view}")
puts "#{$?.exitstatus}"
puts cmd_result
does not return any output and the exit status is 1. when run with puppet.
but if I ran it manually it works normally.
You are (I think) trying to run ruby code from Puppet.
Puppet uses a DSL written in ruby. I suggest you get started here

How do I to run a command in Linux as a Ruby script?

Let's say I have some terminal commands like:
sudo mycommand1
mycommand2
#.....
What should I do run them via ruby script (not bash) in Ubuntu?
UPDATE:
I have a ruby script:
def my_method1()
#calculating something.....
end
def method2(var1, var2)
#how do I sudo mycommand1 and any other Lunix command from here?
end
def method3(var4)
#calculating something2....
end
You can do system, exec, or place the command in backticks.
exec("mycommand") will replace the current process so that's really only pratical at the end of your ruby script.
system("mycommand") will create a new process and return true if the command succeeded and nil otherwise.
If you need to use the output of your command in your Ruby script use backticks:
response = 'mycommand`
There are many questions on SO that answer this. However you can run a command in many ways using system, exec, (backticks), %x{} or using open3. I prefer to use open3 -
require 'open3'
log = File.new("#{your_log_dir}/script.log", "w+")
command = "ls -altr ${HOME}"
Open3.popen3(command) do |stdin, stdout, stderr|
log.puts "[OUTPUT]:\n#{stdout.read}\n"
unless (err = stderr.read).empty? then
log.puts "[ERROR]:\n#{err}\n"
end
end
If you want to know more about other options you can refer to Ruby, Difference between exec, system and %x() or Backticks for links to relevant documentation.
You can try these approaches:
%x[command]
Kernel.system"command"
run "command"
make some file.rb with:
#!/path/to/ruby
system %{sudo mycommand1}
system %{mycommand2}
and the chmod the file with exec permissions (e.g. 755)
It you need to pass variables between the two commands, run them together:
system %{sudo mycommand1; \
mycommand2}

Log process output

I used the method system to start a process. the pid of that process is being stored in a file worker.pid
however I need to generate the log of this process, how can I store the output of this process?
the process is being created with this command:
system "bundle exec rake resque:work >> ./resque.log QUEUE=* PIDFILE=#{pid_file} &"
P.S.: I am using ruby 1.8, BACKGROUND=yes won`t work.
P.S.2: platform linux
Maybe what you're looking for is IO.popen
This lets you fork off a subprocess and access it's output via an IO object
# fork off a one-off task
# and return the output as a string
ls = IO.popen("ls")
ls.read
# or return an array of lines
IO.popen("ls").readlines
# or create a continuing task
tail = IO.popen("tail -f /some/log/file.log")
loop do
puts tail.gets
end
I suggest you read the documentation,
but you can also write to the stream, and do all sorts of clever stuff.
If I'm understanding what you are trying to achieve correctly, you are looking for the Open3 class. http://www.ruby-doc.org/stdlib-1.8.7/libdoc/open3/rdoc/Open3.html

Resources