I'm using uname -n as an example. I've tried other shell commands, using the full pathname to the shell command, and I used other delimiters, such as %x( ) and %x[ ].
$ uname -n
my-server
$ which env
/usr/bin/env
$ which ruby
/home/ubuntu/.rvm/rubies/ruby-2.2.1/bin/ruby
$ irb
2.2.1 :001 > %x{uname -n}
=> "my-server\n"
2.2.1 :002 > exit
$ cat ET.rb
#!/usr/bin/env ruby
%x{uname -n}
$ ruby ET.rb
$ ### !!!?!?!? I'm expecting "my-server"
In IRB, it will show the results of any Ruby statements you feed it. But if in a Ruby script, you should use puts or print method to print something out:
puts %x{uname -n}
or:
print %x{uname -n}
Related
My question is similar to this one: How to detect if my shell script is running through a pipe?. The difference is that the script I’m working on is written in Ruby.
Let’s say I run:
./test.rb
I expect text on stdout with color, but
./test.rb | cat
I expect the color codes to be stripped out.
Use $stdout.isatty or more idiomatically, $stdout.tty?. I created a little test.rb file to demonstrate, contents:
puts $stdout.isatty
Results:
$ ruby test.rb
true
$ ruby test.rb | cat
false
Reference: https://ruby-doc.org/core/IO.html#method-i-isatty
Use IO#stat.pipe?.
IO#tty? returns true only on a TTY device.
Returns false for UNIX-style pipes (see "man 2 pipe").
$ echo "something" | ruby -e 'puts $stdin.stat.pipe?'
true
$ echo "something" | ruby -e 'puts $stdin.tty?'
false
$ ruby -e 'puts $stdin.tty?'
true
Consider oneliner
$ ruby -e 'puts 1 + 1'
which uses ruby as a command-line calculator. I would like to write the expression without puts. Is there a switch for it in ruby command?
It is impossible with ruby command line switches, but it’s easily achievable with shell:
⮀ cat /usr/local/bin/rubyoneliner
#!/bin/sh
ruby -e "puts $#"
⮀ rubyoneliner '1 + 1'
2
or with bash/zsh function.
There is no way to have an implicit print in ruby. However, you can shrink your oneliner a little more -> replacing puts by p and including the require in the shell command :
$ ruby -rsy -e 'p 42.kWh.in :MJ'
-rsy whould replace the require 'sy'.
Otherwise you can use the fact that the option -p, implicitely puts the $_ variable with something like (much longer however) :
$ printf whatever | ruby -rsy -pe '$_ = 42.kWh.in :MJ'
or uglier
$ printf whatever | ruby -rsy -pe 'sub("whatever", 42.kWh.in :MJ)'
I have a ruby bin I'd like to pass information to in this fashion:
some_text | ./bin/my_ruby_bin
where some_text will be accessible by ARGV
is this possible with ruby + shell or am I taking the wrong approach here?
Here is simple solution that works for my cause, but it appears there are many ways to do this:
# ./bin/my_ruby_bin
#!/usr/bin/env ruby -n
puts "hello: #{$_}"
notice the -n flag
from command line:
echo 'world' | ./bin/my_ruby_bin
# => hello world
More on ruby -n
ruby -h
-n assume 'while gets(); ... end' loop around your script
I needed to know what was in my Ruby load path, so I did this:
$ ruby -e "puts $LOAD_PATH"
It didn't print anything out, which I didn't expect. So I tried this:
$ ruby -e "puts $:"
/usr/local/lib/site_ruby/1.8
/usr/local/lib/site_ruby/1.8/i486-linux
/usr/local/lib/site_ruby/1.8/i386-linux
/usr/local/lib/site_ruby
/usr/lib/ruby/vendor_ruby/1.8
/usr/lib/ruby/vendor_ruby/1.8/i486-linux
/usr/lib/ruby/vendor_ruby
/usr/lib/ruby/1.8
/usr/lib/ruby/1.8/i486-linux
/usr/lib/ruby/1.8/i386-linux
.
Why does the second one give me the expected output and the first one doesn't? Shouldn't they be the same? I just tried it in irb, and I got the results I expected.
This is my Ruby version, in case it makes a difference:
$ ruby --version
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
They are not. Try running this command:
$ ruby -e 'puts $LOAD_PATH'
which doesn't make shell expand $LOAD_PATH due to use of ' instead of ".
What's up with this, how do I capture the output from my Gambit-C program?
$ gsi -e "(pp 'hello?)"
hello?
$ gsi -e "(pp 'hello?)" >asdf
hello?
$ gsi -e "(pp 'hello?)" 2>asdf
hello?
$ cat asdf
It should have put the output of the program into asdf, but it's empty!
Is there a compile-time or run-time option I can set to make it treat stdout like a normal unix program? (Preferably compile-time)
I am not familiar with pp, but you seem to want pretty-print:
$ gsi -e "(pretty-print 'hello?)" > test
$ cat test
hello?
$