My employer has Ruby 1.8.7 in the /usr/bin/ruby, and allows the usage of Ruby 2.4 only via SCL (sofoware collections).
Which means that when I run ruby, I need to use (from the RH6 shell) scl enablde ruby-24 'ruby foo.rb' when foo.rb
is the file name.
I want to enable the ruby call on the first execution line, i.e., instead of the Ruby code file looking like:
#!/usr/bin/ruby
puts "Hello world"
That the code will look
#!cmd
puts "Hello world"
Where the cmd is what calls via the scl and run the Ruby 2.4 for the puts command. I know that a wrapper file can be used. I want something in 1 file.
How about this:
#!/usr/bin/ruby
if RUBY_VERSION != "2.4.1"
exec "scl enable ruby-24; ruby __FILE__"
end
puts "Ruby Version: #{RUBY_VERSION}"
Related
I'd like to write a ruby script that then calls another ruby script. Example, I'd like to run the "test1.rb" from my script. The test1.rb has been simplified to just do this:
print "1"
Then get the result (-> 1).
I ask to help others to fix this problem, and they suggested the popen3 command:
require 'open3'
cmd = 'ruby "test1.rb"'
puts Dir.pwd
Open3.popen3(cmd) do |stdin, stdout|
var = stdout.read
puts var
end
However, the script send an error message:
X:/Ruby22-x64/lib/ruby/2.2.0/open3.rb:193:in `spawn': No such file or directory
- ruby "test1.rb" (Errno::ENOENT)
Please help me.
I'd like to enter the debugger upon typing ctrl-C (or sending a SIGINT). I have installed the debugger (I'm running Ruby 1.9.3) and verified that it works. I've added this to my setup files (this is for Padrino, but I assume it would be similar for Rails):
# file: config/boot.rb
Padrino.before_load do
trap("SIGINT") { debugger } if Padrino.env == :development
end
... but typing Ctrl-C does not invoke the debugger. In fact, if I replace debugger with puts "saw an interrupt!", typing Ctrl-C doesn't cause a print to happen either.
update
Following this suggestion from Mike Dunlavey, I tried explicitly calling catch Interrupt from within the debugger:
$ rdebug `which padrino` console
^Z^Z$HOME/usr/bin/padrino:9
require 'rubygems'
(rdb:1) catch Interrupt
Catch exception Interrupt.
(rdb:1) c
=> Loading development console (Padrino v.0.10.7)
=> Loading Application BlueDotAe
=> Loading Application Admin
irb(main):001:0> C-c C-c^C
irb(main):001:0>
No joy -- interrupt did not enter the debugger.
What am I missing?
If you want to trap SIGINT while running in the console, the short answer is: you cannot unless you monkey-patch IRB. Every Ruby app (whether padrino, or rails or whatnot) that uses the console will end up calling usr/lib/ruby/1.9.1/irb.rb, and in IRB.start, it does:
trap("SIGINT") do
irb.signal_handle
end
... just before entering the main loop. This will override any trap("SIGINT") you might have put in your startup code.
But if you want to trap SIGINT in a script file (for example, if you want to profile your code as described by Mike Dunlavey here), you can create a script file such as:
# File: profile_complex_operation.rb
trap("SIGINT") { debugger }
MyApp.complex_operation
and then invoke it as in:
$ ruby profile_complex_operation.rb
Now, when you hit ^C (or send SIGINT from another process), it will enter the debugger.
You may try to use GDB wrapper for Ruby (GitHub).
Install on Linux via:
sudo apt-get install gdb python-dev ncurses-dev ruby-rvm
gem install gdb.rb
Basic usage:
require 'gdb'
# create a new GDB::Ruby instance and attach it to
# pid 12345
gdb = GDB::Ruby.new(12345)
# print the (ruby) backtrace of the remote process
gdb.backtrace.each { |line| puts line }
# show the current local variables, and their values
p gdb.local_variables
# evaluate arbitrary ruby code in the remote process
p gdb.eval('%(pid #{$$})')
# show how many instances of each class exist in the
# remote process
p gdb.object_space
# raise an exception in the remote process
gdb.raise Exception, "go boom!"
# close the connection to the remote process
gdb.quit
Or to debug the hung process, attach it via:
rvmsudo gdb.rb PID
then:
# in gdb get a ruby stacktrace with file names and line numbers
# here I'm filtering by files that are actually in my app dir
(gdb) ruby eval caller.select{|l| l =~ /app\//}
Source: Using gdb to inspect a hung ruby process
Some alternatives:
rbtrace - like strace, but for ruby code (usage: rbtrace -p <PID> --firehose).
debug.rb script by tmm1 (author of gdb.rb) which can help to debug a process using strace/gdb.
See also:
Debugging Ruby Tools
Check why ruby script hangs
Let's say I have some terminal commands like:
sudo mycommand1
mycommand2
#.....
What should I do run them via ruby script (not bash) in Ubuntu?
UPDATE:
I have a ruby script:
def my_method1()
#calculating something.....
end
def method2(var1, var2)
#how do I sudo mycommand1 and any other Lunix command from here?
end
def method3(var4)
#calculating something2....
end
You can do system, exec, or place the command in backticks.
exec("mycommand") will replace the current process so that's really only pratical at the end of your ruby script.
system("mycommand") will create a new process and return true if the command succeeded and nil otherwise.
If you need to use the output of your command in your Ruby script use backticks:
response = 'mycommand`
There are many questions on SO that answer this. However you can run a command in many ways using system, exec, (backticks), %x{} or using open3. I prefer to use open3 -
require 'open3'
log = File.new("#{your_log_dir}/script.log", "w+")
command = "ls -altr ${HOME}"
Open3.popen3(command) do |stdin, stdout, stderr|
log.puts "[OUTPUT]:\n#{stdout.read}\n"
unless (err = stderr.read).empty? then
log.puts "[ERROR]:\n#{err}\n"
end
end
If you want to know more about other options you can refer to Ruby, Difference between exec, system and %x() or Backticks for links to relevant documentation.
You can try these approaches:
%x[command]
Kernel.system"command"
run "command"
make some file.rb with:
#!/path/to/ruby
system %{sudo mycommand1}
system %{mycommand2}
and the chmod the file with exec permissions (e.g. 755)
It you need to pass variables between the two commands, run them together:
system %{sudo mycommand1; \
mycommand2}
install rvm in one line example:
user$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
Now, say I have a ruby scripts like this at http://blah.com/helloworld.rb
puts "what's ur name?"
name = gets.chomp
puts "hello world from web, #{name}"
I would like to achieve this it in my shell without creating a temp file in one line or even better one command.
wget http://blah.com/helloworld.rb; ruby helloworld.rb; rm helloworld.rb
I have tried this, but user prompt will be ignored because of earlier pipe.
curl -s http://blah.com/helloworld.rb | ruby
What's the correct way to executing a remote ruby script? Thanks!
Like this:
ruby < <(curl -s http://blah.com/helloworld.rb)
Ruby evaluates ruby code similarly to how bash evaluates shell code
Another Ruby option based on Calibre install for shell scripts:
ruby -e "require 'open-uri'; system open('http:// or local file').read"
The same for Ruby scripts:
ruby -e "require 'open-uri'; eval open('http:// or local file').read"
Edited: Fixed missing quote and added Ruby script execution
From http://brew.sh/:
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
In your Ruby code, you have to reopen stdin and tie it to the controlling terminal device /dev/tty!
rubyscript="$( cat <<-'EOF'
puts "what's ur name?"
name = gets.chomp
puts "hello world from web, #{name}"
EOF
)"
ruby <(echo '$stdin.reopen(File.open("/dev/tty", "r"))'; echo "$rubyscript")
I need to run a standalone ruby script as Unix (linux) daemon.
After running that daemon I need to run another Ruby method with it.
I installed the ruby-daemon gem on my machine by using the gem install daemon.
I did the test daemon program.
My test.rb file is :
module Test
def test_method
#s =" ITS WORKING !"
file=File.new("/home/username/test.txt", "w")
file.puts #s
file.close
end
end
My test_control.rb file is :
# this is myserver_control.rb
require 'rubygems' # if you use RubyGems
require 'daemons'
Daemons.run('test.rb')
After this I run the following command: ruby test_control.rb start
Now how can I check whether the daemon program has started properly?
How can I invoke a method with it?
Looks like the formatting on your post is way off, so hopefully someone can fix that, but I think the problem here is you're defining a module but not actually firing off the method you define.
The Daemons utility only executes the script provided. You should test that your "test.rb" file can be run on the command line directly before trying to diagnose what might be wrong with Daemons itself.
It may be as reworking test.rb:
module Test
def self.test_method
#s =" ITS WORKING !"
file = File.new("/home/username/test.txt", "w")
file.puts #s
file.close
end
end
Test.test_method
There are other ways to use Daemons where you pass it a module to run, but you're not using it that way.