run commands in openssl from ruby - ruby

I'm trying to run the following commands over ssh in ruby.
[root#test]# /usr/local/ssl/bin/openssl
OpenSSL> version
1.0.2d
OpenSSL> exit
Here's my code :
def execute(cmd)
puts cmd
result = con.exec!(cmd)
result = result.strip! unless result==nil
p "command output execute() :: #{result}"
return result
end
con.execute("/usr/local/ssl/bin/openssl && version && exit")
The first command leads to OpenSSL prompt. How do I run commands in it?

Related

Multiple shell commands executed in one process in groovy script

I want to fetch a npm package and untar it in a groovy script like so:
def cmd = "cd .composerpages/umanagement && npm pack #mag-umanagement/umanagement-pages-v2810#^28.10.4-SNAPSHOT && tar xvzf *.tgz"
cmd.execute()
Unfortunately, it executes only the first term (cd .composerpages/umanagement).
Is there a way to have multiple commands executed in one shell process?
If you need all the "shell-isms" there, then just let the shell handle it (with -c). E.g.:
def cmd = "cd .composerpages/umanagement && npm pack #mag-umanagement/umanagement-pages-v2810#^28.10.4-SNAPSHOT && tar xvzf *.tgz"
["/bin/sh", "-c", cmd].execute()
I think you need to execute all the options and not && them.
This is how you should approach it:
def cmd = 'cd .composerpages/umanagement'.execute() | 'npm pack #mag-umanagement/umanagement-pages-v2810#^28.10.4-SNAPSHOT'.execute() | 'tar xvzf *.tgz'.execute()
cmd.waitFor()
println cmd.text
In this case you can try tokenizing your pipeline of commands to a list of commands and execute them in sequence as long as they return exit code 0 (&& stops command pipeline when the command returns nonzero exit code). Consider following example:
def cmd = 'echo test && echo foo && exit 1 && echo 123'
cmd.tokenize('&&').every {
try {
def p = it.execute()
def output = p.text.trim()
p.waitFor()
println output
return p.exitValue() == 0
} catch (e) {
return false
}
}
Here we have a pipeline of 4 commands:
echo test
echo foo
exit 1
echo 123
Chaining these commands with AND operator (&&) expects stopping the pipeline after exit 1.
Groovy's Iterable.every(Closure closure) method executes as long as returned predicate is true. In our case we continue iterating over the list of commands as long as exit code is 0.
Running above example produces following output to console:
test
foo

How do i run Ruby script from command line ?

I've a file, which I can run from command line using:
ruby filename.rb
Which outputs:
12345
A different script containing:
def hi()
puts "hello"
end
does not return anything when I run it from the command-line.
How do I run this from the command line?
Add puts hi("John") to the bottom of the method:
def hi(name)
puts "hello"
end
puts hi("John")
Where "John" is whatever name you want it to be.
Then just run it as usual, ruby yourfilename.rb
Try putting this in filename.rb:
def hi()
puts "hello"
end
hi
Then run your code in the command line: with ruby filename.rb

Get PowerShell output in Ruby

I am writing some automation script that needs to run PowerShell commands on a remote machine using Ruby. In Ruby I have the following code:
def run_powershell(powershell_command)
puts %Q-Executing powershell #{powershell_command}-
output = system("powershell.exe #{powershell_command}")
puts "Executed powershell output #{output}"
end
I can pass in Invoke-Command based ps1 files and everything works as expected. I can see the output in the console when I run the command.
The only problem is that there is no way to find out if the command run was successful; sometimes PowerShell is clearly throwing errors (like not able to get to the machine), but the output is always true.
Is there a way to know if the command ran successfully?
system(...) will actually return a value saying if it succeeded, not the output of the call.
So you can simply say
success = system("powershell.exe #{powershell_command}")
if success then
...
end
If you want both the output and return code, you can use `backticks` and query $? for the exit status (not the same $? as linked to in the comment to the question, by the way.)
output = `powershell.exe #{powershell_command}`
success = $?.exitstatus == 0
If you want a more reliable way that will escape things better, I'd use IO::popen
output = IO::popen(["powershell.exe", powershell_command]) {|io| io.read}
success = $?.exitstatus == 0
If the problem is that powershell itself isn't exiting with an error, you should have a look at this question
There is another option, and that is running the PowerShell from cmd. Here is the (pretty hard to figure out) syntax:
def powershell_output_true?()
ps_command = "(1+1) -eq 2"
cmd_str = "powershell -Command \" " + ps_command + " \" "
cmd = shell_out(cmd_str, { :returns => [0] })
if(cmd.stdout =~ /true/i)
Chef::Log.debug "PowerShell output is true"
return true
else
Chef::Log.debug "PowerShell output is false"
return false
end
end
I am comparing the stdout to true, but you can compare it to whatever you need.
described in blog

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 do I get the exit status for a command invoked with IO.popen?

I am using IO.popen to execute a command and am capturing the output like so:
process = IO.popen("sudo -u service_user -i start_service.sh") do |io|
while line = io.gets
line.chomp!
process_log_line(line)
end
end
How can I capture the exit status of *start_service.sh*?
You can capture the exit status of a command invoked via IO.open() by referencing $? as long as you have closed the pipe at the end of your block.
In the example above, you would do:
process = IO.popen("sudo -u service_user -i start_service.sh") do |io|
while line = io.gets
line.chomp!
process_log_line(line)
end
io.close
do_more_stuff if $?.to_i == 0
end
See Ruby Core Library entry for IO.popen for more information.

Resources