Search code examples
ruby-on-railsrubysshremote-accessremote-execution

run the shell script from rails application after login to the remote system


I want to run a shell script from my Rails application. The script is started on the remote server via the net-ssh Gem. Here is my code:

Net::SSH.start('localhost', 'user', :password => '1234', :port => port) do |session|
  session.exec!("#{Rails.root}/script/myscript")
end

I have checked that the script is present in my local application. Script is taking about 1 hour for completion. I have two questions:

  1. Is this the right way for doing this?
  2. How can I run the script in the background?

Solution

    1. The sample doc says that the simple, and quite proper way to run the Net::SSH session is the following:

      HOST = '192.168.1.113'
      USER = 'username'
      PASS = 'password'
      
      Net::SSH.start( HOST, USER, :password => PASS ) do| ssh |
         result = ssh.exec! 'ls'
         puts result
      end
      

      I recomment to pass at least password argument via shell environment to don't store it in the script plainly. Also you could use micro-optparse gem to pass other argument via command line. So it could be as follows:

      require 'micro-optparse'
      
      options = Parser.new do |p|
         p.banner = "This is a fancy script, for usage see below"
         p.version = "fancy script 0.0 alpha"
         p.option :host, "set host", :default => 'localhost'
         p.option :host, "set user", :default => ''
      end.parse!
      
      Net::SSH.start( options[ :host ], options[ :user ], :password => ENV[ 'PASSWORD' ] ) do| ssh |
         result = ssh.exec! 'ls'
         puts result
      end
      

      And run from command line:

      $ bundle exec ./1.rb --host=111.ru --user=user
      {:host=>"111.ru", :user=>"user"}
      

      Of course the support for :port argument can be added in the same manner.

    2. Use nohup or screen utitilies to run a script as a service in linux:

      result = ssh.exec! "nohup #{Rails.root}/script/myscript"