Running a Ruby Script from Rails controller kills the rails server

90 views
Skip to first unread message

Sam S

unread,
Oct 13, 2015, 7:56:28 AM10/13/15
to Ruby on Rails: Talk
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?


 

 

Frederick Cheung

unread,
Oct 13, 2015, 8:05:17 AM10/13/15
to Ruby on Rails: Talk


On Tuesday, October 13, 2015 at 12:56:28 PM UTC+1, Sam S wrote:
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

Matt Jones

unread,
Oct 13, 2015, 2:08:16 PM10/13/15
to Ruby on Rails: Talk


On Tuesday, 13 October 2015 07:56:28 UTC-4, Sam S wrote:
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. 

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
Reply all
Reply to author
Forward
0 new messages