Ruby directly from command line - ruby

I know that I can run ruby code directly from the command line, like so:
ruby file.rb
But is there any way to run ruby code directly from the command line so that I don't have to save the file in the first place?

ruby -e 'puts("foobar :)"); puts(2 + 2)'
should print foobar :) and 4

The quick help invoked using ruby -h says:
$ ruby --help
Usage: ruby [switches] [--] [programfile] [arguments]
...
-e 'command' one line of script. Several -e's allowed. Omit [programfile]
...
#djaszczurowski's answer provides you an example.
Another, better, option is to use irb (the interactive Ruby interpreter). It displays a prompt and waits for you to enter Ruby code. Multiple lines of code can be entered; it is executed when the block is closed.
#ho-man's answer shows you how to use it.

If you have more code that you'll like to run you can use irb instead.
$ irb
2.4.1 :001 > puts (2+2)
4
=> nil

Related

Ruby only executing the first line?

I'm writing a ruby script and found this strange behaviour.
Using ruby 2.4.2 [x86_64-darwin16]
Basically I'm trying to echo two separated messages and in my index.rb file I got:
exec("echo 'teste'")
exec("echo 'teste2'")
But when I run ruby ./index.rb
The output is:
teste
Why that's happening?
Shouldn't this be the output?
testeteste2
exec([env,] command... [,options])
Replaces the current process by running the given external command docs
It means that the first call to exec replaces your ruby program with echo, so the rest of the ruby program is not executed.
You can use backticks to run a command like you want:
`echo 'teste'`
`echo 'teste2'`

When specifying command-line arguments Ruby no longer waits for input using gets

When running a ruby script with command line arguments, the "gets" is no longer blocking, it doesn't work.
test.rb
#!/usr/bin/ruby
puts "should wait for input"
gets
puts "test"
and here is how I run it
$ ./test.rb test.rb
should wait for input
test
It didn't wait.
I'm running Ubuntu 16.04 desktop, and Ruby from repository ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu]
What am I doing wrong?
In addition to STDIN.gets like others have recommended, you can use plain gets if you call ARGV.clear beforehand. The regular gets works as expected if there aren't command like arguments to the script, but if there are, then it will read them. It's not really clear why you're using ./test.rb test.rb, but the second filename is a command line argument.
More specifically, if regular gets is called when ARGV is populated, then the result will be the contents of the file.
max#max ~> echo "content" > test.txt
max#max ~> ruby -e "puts ARGV.inspect; puts gets" test.txt
["test.txt"]
content
Nevermind,
The "gets" actually takes the first line from the file I added in the cli arguments.
Very weird.

how to build wrapper script

Sort of an odd question, but: how would one go about creating a wrapper shell script that can be used in the #! line in other scripts.
wrap.sh
#!/bin/bash
set -e
echo "wrapper!"
exec ruby "$#"
test.rb
#!/usr/bin/env wrap.sh
puts RUBY_VERSION
puts "the ducks come from the trucks"
wrap.sh is in the path, and test.rb is marked as executable.
Now I do:
./test.rb
wrapper!
ruby: no Ruby script found in input (LoadError)
The goal is to execute the ruby script via the wrapper (The ruby version can be either local or comes from a traveling ruby install that is shipped along with the app).
As far as I can tell ruby is invoked, it's just unhappy with the #! in the test.rb and refuses to run the script. I cannot remove the #! because that's how the script is executed in the first place.
Any workarounds for this?
So, I cannot use rbenv/rvm/etc. There is more logic in the wrapper than this, but this is the gist of it.
Looks to me like the arguments are not being passed to Ruby in "$#". I don't think the bang-hash line is the problem.
I don't see anything in your script which actually passes the contents of test.rb to wrapper.sh, which is the bigger issue.
Perhaps the real problem can be solved by some other means? For example, is the problem you're trying to solve to run arbitrary commands prior to the invocation of any Ruby script from the command line? Perhaps it can be approached that way...
It looks like Ruby just checks that the hash-bang line contains "ruby": https://github.com/ruby/ruby/blob/v2_2_2/ruby.c#L1580 So basically having ruby somewhere in the #! line is all it takes.

Ruby - How to use -r switch with ruby command line tool

I was trying to figure out how to work the command line switch -r.
My understanding is that the code is typed out as follows:
ruby -r*nameOfRequired*
I am finding that this is not the case. When I type out the above and press enter, the terminal expects an "end of input syntax" and does not continue.
What am I missing? Does there need to be a space in between the switch and the name of the required file?
Please and thank you!
EDIT:
I am currently reading "The Well Grounded Rubyist" by David A. Black, and I came up with this question while reading the section on command line switches.
Having said that, I created a "test.rb" file, containing:
puts Date.today
Then, in the terminal, I typed out:
ruby -r date
I thought this would 'require' the date module, and then enable me to run the "test.rb" file, using ruby test.rb (given that I am in the correct directory).
Instead, the terminal cursor moves to a newline, expecting more input. Let me know if I need to clarify anything else. Thanks!
If you just type ruby -rmodule, then Ruby will load the module and wait for you to type the main program that requires that module.
If you just want to run the module and do nothing else, you can do do rubyfull-path-to-module without the -r, or ruby -rmodule -e exit, or ruby -rmodule </dev/null, or similar.
In general, the ruby command does not record any state from one run to the next, so you need to tell it every thing that it needs to know whenever you run it.
Whenever you run it, you need to tell it the main program to run or else it will expect you to type that program on the standard input. The -r does not specify the main program.
Try this:
ruby -rdate test.rb
According to ruby -h:
-rlibrary require the library, before executing your script
Without giving your script file path, it read the script from stdin.
Try following (You can omit script file path when you give -e command):
ruby -r**nameOfRequired** -e ""

echo back every Ruby code line like sh -x?

Is there a way to have a ruby script echo back (or log to file I can tail -f) every line executed, similar to bash -x or #echo on in DOS?
ruby -w doesn't do it--only increases verbosity of warnings etc.
Researched Unroller but it doesn't work, possibly too dated. Uncompilable dependencies.
I use irb a lot but in this case I need something non-interactive eg. to inspect post-mortem.
You can use
ruby -rtracer [your_script.rb]
There is also ruby-debug which can do
rdebug --trace [your_script.rb]
IRB does the trick:
irb script.rb

Resources