How to print the output on the console? - ruby

I am trying to show the "curl's" output on the console when I execute it. Below is what I wrote. It prints the statement that I declared in puts for all the hostnames, which is as per designed.
desc "check_app_version <environment> <project>", "checks the /dev/info page of the app"
def check_app_version(environment, project)
check_environment(environment)
machines = `knife node list`.split
machines.each do |hostname|
puts "checking the app-version for #{hostname}"
system("curl --silent -m 5 #{hostname}:8080/dev/info |grep 'Application\|Build'")
end
end
But I don't see anything for the next line which instructs to perform a curl on my servers.

Use the backtick notation to return a string, then return to puts
puts `curl --silent -m 5 #{hostname}:8080/dev/info |grep 'Application\|Build'`

puts `curl --silent -m 5 #{hostname}:8080/dev/info |grep 'Application\\|Build'`

Related

How to check if 'ARGV' contains both '-p' and '-c' in optparse

This code is intended to check whether the user entered an option with the command:
require 'optparse'
ARGV << '-h' if ARGV.empty?
options = {}
OptionParser.new do |parser|
parser.banner = "Usage: myruby.rb [options]"
parser.on("-h", "--help", "Help myruby") do | |
puts parser
exit
end
parser.on("-p", "--people PEOPLE", "PPPPPPPPPP") do |v|
options[:pppp] = v
end
parser.on("-c", "--coordinate COORDINATE", "ccccccccc") do |x|
options[:coordinate] = x
end
end.parse!
# Start my program from this line
unless options[:pppp] && options[:coordinate]
puts "Exit OK because missing both (option and argument) p,c"
exit
end
puts "It work if only run myruby.rb -p argument_P -c argument_c"
I just found an error. If the user enters only one but not both required ARGV (-p -c).
I can check and exit from my application, but I want to filter ARGV by exiting to assign ARGV << 'h'.
What is the best way?
updated 1: Added unless case before run my program problem : Worked as
asked, but error when -p or -c missing argument. example : ruby
thiscode.rb -p bababa -c error : rb:17:in `': missing
argument (OptionParser::MissingArgument)
Just explicitly check the presence of both after options are parsed:
unless options[:pppp] && options[:coordinate]
puts USAGE # or do whatever else
exit
end

How to change rvm gemset over ssh on os x server

ok
I don't know how to change rvm version over ssh under os x server.
What I do:
Login on server over ssh
run script (below) and catch error
Error: 'rvm is not a funciton, many-many-words'
What I have as script:
use File::Spec;
my $server_directory = File::Spec->catfile($ENV{HOME},'MyProject');
my $exec_file = File::Spec->catfile($server_directory,'run_script.rb');
my $run_ruby_script = qq'bundle exec ruby $exec_file'.' '.join(' ',#ARGV);
# reload bash profile
print qx(source $ENV{HOME}/.bash_profile);
print qx(source $ENV{HOME}/.bashrc);
# reload ruby
print qx(source $ENV{HOME}/.rvm/scripts/rvm);
my $ruby_setup = qq([[ -s "$ENV{HOME}/.rvm/scripts/rvm" ]] && source "$ENV{HOME}/.rvm/scripts/rvm");
print $ruby_setup. "\n";
# change directory
chdir($server_directory);
# configure gemset name
my $version = qx(cat .ruby-version);
chomp($version);
my $gemset = qx(cat .ruby-gemset);
chomp($gemset);
my $change_rvm_gemset = qq(rvm use $version\#$gemset);
print qx($ruby_setup && $change_rvm_gemset);
print qx(rvm current);
Ok, after all.
def exec_via_bash(line)
puts %Q(#{line})
exec = 'bash -c "#{line}"'
puts `#{exec}`
end
def RubySetup
# reload bash profile
homedir = ENV['HOME']
exec_via_bash %Q(source #{homedir}/.bash_profile);
exec_via_bash %Q(source #{homedir}/.bashrc);
# reload ruby
exec_via_bash %Q(source #{homedir}/.rvm/scripts/rvm);
ruby_setup = %Q([[ -s "#{homedir}/.rvm/scripts/rvm" ]] && source "#{homedir}/.rvm/scripts/rvm")
puts ruby_setup
ruby_setup
end
if ARGV.empty?
puts "there is not enough arguments passed. maybe you forget ruby file to exec?"
exit(1)
end
ruby_script_path = ARGV.shift;
exec_file_absolute_path = File.expand_path(ruby_script_path)
unless File.exists? exec_file_absolute_path
puts "file #{exec_file_absolute_path} doesn't exists!"
exit(1)
end
exec_file_directory = File.dirname(exec_file_absolute_path)
exec_bundle = %Q'bundle exec ruby #{exec_file_absolute_path}' + ' ' + ARGV.join(' ')
# change directory
Dir.chdir(exec_file_directory);
# print %x(ls);
# configure gemset name
version = %x(cat .ruby-version).strip;
gemset = %x(cat .ruby-gemset).strip;
change_rvm_gemset = %Q(rvm use #{version}\##{gemset});
ruby_setup = RubySetup()
exec_bash_login_line = [ruby_setup, change_rvm_gemset, exec_bundle].join ' && ';
puts 'exec bash login line: ' + exec_bash_login_line
forced = %Q(bash --login -c '#{exec_bash_login_line}');
puts forced, "\n";
puts %x(#{forced});
ok, this script is not a kind of beauty, but it works well.
Example of usage?
ruby script.rb ~/bla/bla/bla/run_your_program.rb --first_argument --second_argument a,b,c --etc
As I said before:
I've already on the server via ssh.
So, I need to run scripts via launchd.
And I should do it with
# part of launchd worker
<string>bash</string>
<string>-c</string>
<string>ruby ~/PathToCharmScript.rb -r a</string>
P.S:
Please, help me with improvements of this script for others!
Here is a gist: wow_this_works

How can I get the output of an ssh command?

I'd like to programmatically check if someone has their SSH keys set up correctly for GitHub. I understand that I can use `ssh -T git#github.com` in Ruby. However, I'd like to keep the ssh output in a variable.
My current code is:
github_response = `ssh -T git#github.com`
unless github_response.start_with?('Hi')
puts 'Please set up your GitHub ssh keys'
end
`ssh -T git#github.com` outputs the response (starting with "Hi"). However the github_response variable is nil.
How can I assign the output of `ssh -T git#github.com` to github_response?
Your example failed because the Hi xxx! You've successfully authenticated.... message is not from stdout, but stderr.
> require 'open3'
=> true
> stdin, stdout, stderr, wait_thr = Open3.popen3('ssh -T git#github.com')
=> [#<IO:fd 8>, #<IO:fd 9>, #<IO:fd 11>, #<Thread:0x007f89ee1149a8 sleep>]
> stdout.gets
=> nil
> stderr.gets
=> "Hi halfelf! You've successfully authenticated, but GitHub does not provide shell access.\n"
You could add -v for verbose output, it will then dump much of the connection info to stdout. From that log you can scrape to find whether the server accepted any of the keys the ssh client offered

Running command line commands from Thor executable

In my executable Ruby file I have the following:
#!/usr/bin/env ruby
require 'thor'
include Thor::Actions
class UI < Thor
# def self.source_root
# File.dirname(__FILE__)
# end
desc "makecal", "Generates postscript calendar to your desktop"
def makecal
# puts `ls ~`
puts run('ls ~')
# puts run "pcalmakecal -B -b all -d Helvetica/8 -t Helvetica/16 -S #{Time.now.month} #{Time.now.year} > ~/Desktop/#{Time.now.month}-#{Time.now.year}"
end
end
UI.start
In the terminal when I run the file as is I get an empty line as Thor's run command is returning a NilClass.
However, when I un-comment the puts `ls ~` and comment out Thor's run method I get an output of my home directory as expected.
I'm having trouble figuring out why I can't get Thor's run method to work like Ruby's ticks.
Any ideas where I may have went wrong?
Thanks for looking
I didn't put the include statement inside my class and that messed things up. The code should be:
#!/usr/bin/env ruby
require 'makecal'
class UI < Thor
include Thor::Actions
# def self.source_root
# File.dirname(__FILE__)
# end
#
desc "makecal", "Generates postscript calendar to your desktop"
def makecal
# puts `ls ~`
puts run('ls ~')
# puts run "pcal -B -b all -d Helvetica/8 -t Helvetica/16 -S #{Time.now.month} #{Time.now.year} > ~/Desktop/#{Time.now.month}-#{Time.now.year}"
end
end
UI.start
Thor's documentation on this method is actually wrong and incomplete. It documents that it returns the "contents of the command" (which I assume means the standard output), but it, by defualt, does nothing.
But, you can, apparently, use the :capture option to get what you want:
unless options[:pretend]
config[:capture] ? `#{command}` : system("#{command}")
end
So, try doing
puts run("ls ~", :capture => true)
And see if that does it.

How to use getoptlong class in ruby?

I need help using getoptlong class in Ruby. I need to execute command prog_name.ruby -u -i -s filename. So far I can only execute it with prog_name.ruby -u filename -i filename -s filename.
This is my getoptlong code:
require 'getoptlong'
class CommonLog
parser = GetoptLong.new
parser.set_options(["-h", "--help", GetoptLong::NO_ARGUMENT],
["-u", "--url", GetoptLong::NO_ARGUMENT],
["-i", "--ip", GetoptLong::NO_ARGUMENT],
["-s", "--stat", GetoptLong::NO_ARGUMENT])
begin
begin
opt,arg = parser.get_option
break if not opt
case opt
when "-h" || "--help"
puts "Usage: -u filename"
puts "Usage: -i filename"
puts "Usage: -s filename"
exit
when "-u" || "--url"
log = CommonLog.new(ARGV[0])
log.urlReport
when "-i" || "--ip"
log = CommonLog.new(ARGV[0])
log.ipReport
when "-s" || "--stat"
log = CommonLog.new(ARGV[0])
log.statReport
end
rescue => err
puts "#{err.class()}: #{err.message}"
puts "Usage: -h -u -i -s filename"
exit
end
end while 1
if ARGV[0] == nil || ARGV.size != 1
puts "invalid! option and filename required"
puts "usage: -h -u -i -s filename"
end
I'm going to answer by recommending looking at the new-ish "slop" gem. It's a wrapper around getoptlong.
You can use gem install slop if you're using RVM, or sudo gem install slop otherwise.
GetOptLong is very powerful but, though I've used it several times, I still have to go review the docs each time.
If you want a bit more power, with an "easier to use interface than GetOptLong", look into Ruby's OptionParser. You'll need to work out the logic better, but this is a quick pass converting your code. I had to stub out a class for the CommonLog gem because I don't use it. The important stuff follows the line pulling log from ARGV:
require 'optparse'
class CommonLog
def initialize(*args); end
def urlReport(); puts "running urlReport()"; end
def ipReport(); puts "running ipReport()"; end
def statReport(arg); puts "running statReport(#{arg})"; end
end
log = CommonLog.new(ARGV[0])
OptionParser.new { |opts|
opts.banner = "Usage: #{File.basename($0)} -u -i -s filename"
opts.on( '-u', '--[no-]url', 'some short text describing URL') do
log.urlReport()
end
opts.on('-i', '--[no-]ip', 'some short text describing IP') do
log.ipReport()
end
opts.on('-s', '--stat FILENAME', 'some short text describing STAT') do |arg|
log.statReport(arg)
end
}.parse!
Also, as a quick critique, you are not writing idiomatic Ruby code:
when statements can be written: when "-h", "--help"
if ARGV[0] == nil || ARGV.size != 1 is convoluted. Study up on how ARGV and arrays work. Normally, for ARGV[0] to be nil there will be no more arguments, so ARGV.empty? would probably suffice.
you have several errors in the sample program
#each and #get only return the first string in the option and convert the others to it.
You should put that check for arguments before the options processing
You probably don't want this in with your logging class
require 'getoptlong'
# don't pollute CommonLog with this
include CommonLog
# if this is the startup module
if __FILE__ == $0 then
# Check to ensure there are arguments
if ARGV.size < 1
puts "invalid! option and filename required"
puts "usage: -h -u -i -s filename"
end
# set up parser and get the options
parser_opts=GetoptLong.new(
["--help", "-h", GetoptLong::NO_ARGUMENT],
["--url", "-u", GetoptLong::NO_ARGUMENT],
["--ip", "-i", "--ip", GetoptLong::NO_ARGUMENT],
["--stat", "-s", GetoptLong::NO_ARGUMENT]
)
parser_opts.each do |opt,arg|
begin # this is for the exception processing
case opt
when "--help" #only the first option is returned read ruby doc on #each
puts "Usage: -u filename"
puts "Usage: -i filename"
puts "Usage: -s filename"
exit
when "--url" #only the first option is returned
log = CommonLog.new(ARGV[0])
log.urlReport
when "--ip" #only the first option is returned
log = CommonLog.new(ARGV[0])
log.ipReport
when "--stat" #only the first option is returned
log = CommonLog.new(ARGV[0])
log.statReport
else # this should not be used
puts "unexpected option %s"%opt
puts "Usage: -h -u -i -s filename"
end
rescue Exception => err #rescuing an unexpected Exception
puts "#{err.class()}: #{err.message}"
puts "Usage: -h -u -i -s filename"
Kernel.exit
end
end
end

Resources