Running a Ruby Script from Rails controller kills the rails server

I am trying to run a ruby script from my rails controller.

The script runs successfully when the rails server is started normally as

rails s thin -e development

But when rails server is started as a daemon, the ruby script fails to run.

rails s thin -e development -d

Inside the controller the ruby script is run with the exec command.

script_exec = exec(“ruby /Code/AttendanceReport/attn/bin/scripts/Spreadsheet_proper.rb ‘#{city}’ ‘#{date1}’ ‘#{date2}’”)

The above approach kills the rails server and doesn’t execute the ruby script. And hence I used

script_exec = %x{ruby /Code/AttendanceReport/attn/bin/scripts/Spreadsheet_proper.rb ‘#{city}’ ‘#{date1}’ ‘#{date2}’ }

script_exec = system(“ruby /Code/AttendanceReport/attn/bin/scripts/Spreadsheet_proper.rb ‘#{city}’ ‘#{date1}’ ‘#{date2}’”)

The above %x and system approaches also fail when run rails server is started with -d. But it does work when the rails server is normally.

Hence I tried a different approach of using Daemons

In my controller

file_path1 = “/Code/AttendanceReport/attn/bin/scripts/Spreadsheet_proper_control.rb”

script_exec = %x{ruby #{file_path1} start – #{city} #{date1} #{date2}}

The Spreadsheet_proper_control.rb has the

require ‘daemons’

Daemons.run(’/Code/AttendanceReport/attn/bin/scripts/Spreadsheet_proper.rb’)

This approach too fails. Upon logging false value is returned for the above approach.

But when run manually from the terminal, the above Daemon approach is working perfectly.

ruby Spreadsheet_proper_control.rb start – ‘Melbourne’ ‘2015-06-01’ ‘2015-10-01’

The ruby script runs while I am logged into a terminal session and started rails server normally – should that terminal session end so would the server.

Concise app environment:-

  • Ubuntu 14.04

  • Rails version 4.2

  • Ruby 2.2.2

  • daemons (1.2.3)

The Spreadsheet_proper.rb generates an xls file which is then zipped and sent as response by the controller.

Since the output of the ruby script is sent by controller as a response, I couldn’t go for delayed job.

Is there any other approach to run a Ruby script inside Rails controller successfully without the Rails server getting killed when started as daemon?

Inside the controller the ruby script is run with the exec command.

script_exec = exec(“ruby /Code/AttendanceReport/attn/bin/scripts/Spreadsheet_proper.rb ‘#{city}’ ‘#{date1}’ ‘#{date2}’”)

exec replaces the current process, so this is not surprising

The above approach kills the rails server and doesn’t execute the ruby script. And hence I used

script_exec = %x{ruby /Code/AttendanceReport/attn/bin/scripts/Spreadsheet_proper.rb ‘#{city}’ ‘#{date1}’ ‘#{date2}’ }

script_exec = system(“ruby /Code/AttendanceReport/attn/bin/scripts/Spreadsheet_proper.rb ‘#{city}’ ‘#{date1}’ ‘#{date2}’”)

The above %x and system approaches also fail when run rails server is started with -d. But it does work when the rails server is normally.

In what way do they fail?

Fred

How do they “fail”? Is there any output in the terminal, in the system log, or the Rails server logs? If you wrap the call in a begin/rescue block, what is the value in $? Example:

exec_result = begin

system(“do a thing”)

rescue => e

$stderr.puts(e.inspect)

$stderr.puts($?)

exit(-1)

end

Also, I’d recommend being VERY CAREFUL with string interpolation around strings that are handed off to the shell (as the one-argument version of system does). If someone enters their city as “; rm -rf / ; echo” you’re going to have a very bad time, depending on your system’s permissions. Prefer the multi-argument version of system whenever possible:

system(“command name”, “arg1”, “arg2”, “arg3”)

In this form, the arguments are passed straight through to the called program, without ever being expanded / manipulated by the shell.

–Matt Jones