How to store rake task call result in shell? - 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.

Related

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

Command line script that runs a method only when it is executed?

I am building a gem for command line use, and I am aware of the if __FILE__ == $0 method for determining whether the file being run is the current file (from Run code only if script called from the command line), however this doesn't work in my case. I have a module with an initialize function that I would like to run when the gem is called from the command line.
module MyApp
def self.initialize
# do command line stuff
end
def self.test
# run a rake test
end
end
MyApp::initialize
However, when running rake test it calls the initialize function which returns an error:
/Library/WebServer/Documents/myapp ❤ rake test
Options:
-v, --[no-]verbose Run verbosely
-h, --help Show this message
rake aborted!
Command failed with status (255): [ruby -I"lib" -I"/Users/bbriggs/.rvm/gems/ruby-2.0.0-p195/gems/rake-10.1.0/lib" "/Users/bbriggs/.rvm/gems/ruby-2.0.0-p195/gems/rake-10.1.0/lib/rake/rake_test_loader.rb" "test/test_myapp.rb" ]
/Users/bbriggs/.rvm/gems/ruby-2.0.0-p195/bin/ruby_noexec_wrapper:14:in `eval'
/Users/bbriggs/.rvm/gems/ruby-2.0.0-p195/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => test
(See full trace by running task with --trace)
I think this is because I am doing MyApp:initialize, because if I take that out of my code the rake test runs as expected, but the command line tool no longer works.
At the moment I am testing my app via bundle exec bin/myapp, and printing out the __FILE__ and $0 variables give me bin/myapp and path/to/lib/myapp.rb respectively, so I was wondering what the best way is to detect whether the module is being required or called directly. Am I even doing this right? I'm a bit of a Ruby newbie. :-)
Finally figured this out. Instead of running MyApp:initialize in lib/myapp.rb I put it in the bin/myapp file. This ensures that it is only run when the app is run from the command line and not when being tested via Rake or required by another script.

How to print to stdout from system command in Rake?

I have the following Rakefile
desc "Runs tests"
namespace :test do
task :api do
`mocha`
end
end
When I run the command rake test:api, I don't get the nice output of dots that I would if I just ran the command mocha.
How do I print the output of a command real-time in a rake task?
You can just put the output:
puts `mocha`
The backticks ` are calling the command mocha and return the output of the command.
You may also use %x{}:
puts %x{mocha}
Or you use system:
system('mocha')
Or you store the output for later use in a variable:
output = `mocha`
puts output

Ruby file output from fork

I have one simple script:
fork do
STDOUT.reopen(File.open('/tmp/log', 'w+'))
STDOUT.sync = true
exec 'bundle exec ruby script.rb'
end
script.rb:
loop do
sleep 1
puts "MESSAGE"
end
When it work, all outputs is buffering(?) and writes to /tmp/log by big pices.
It works only if I modify script:
$stdout.puts "MESSAGE"
$stdout.flush
How can I do the same without modifying script.rb ?
Thanks.
When you call exec, you create a new process, and although this process inherits the file you set as standard out, it doesn't inherit the other settings, in particular the sync setting.
In order to get unbuffered output in the new process, you need to set it in that process. If you don't want to modify script.rb one workaround could be to create another file, named somethig like sync.rb containing just:
STDOUT.sync = true
which you can then require when running your command:
exec 'bundle exec ruby -r./sync script.rb'
The new Ruby process will now require sync.rb, which simply sets sync mode on STDOUT to true before executing your script.

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