How to use Ruby like shell script?

Y

Yu-Hsuan Lai

[Note: parts of this message were removed to make it a legal post.]

Can I use ruby like my linux shell script(e.x. bash)?(or on the other hand,
use some ruby in shell script)
For example, how to access environmental variables? Redirect stdi/o with '|'
?
If it's valuable, are there some websites/books talking about this?
 
S

Stu

backticks work very well as well and are in the bourne scripting
metaphor. Interpolation (i.e. #{self} will also work inside ruby's
back ticks.

They will return string. to be used within the program. pipes and
redirection can be used inside as so:

ps = "$2"
pid = `ps aux | awk '{print #{ps}}'`
printf pid

$$ gives you the ruby programs process id
$0 returns a string of the program that is running
$* will give you arg list

here = <<FILE
will work as
well which also
include #{interpolation}
FILE

Others can be found in a file called English.rb

~
 
R

Rilindo Foster

Yu,

As much as I liked using Ruby, what exactly are you looking to do with =
ruby that you can't do with bash or ksh?
 
S

Stu

[Note: parts of this message were removed to make it a legal post.]

You also asked for a website resource. I feel this site is pretty venerable:
http://www.shelldorado.com/

I'm sure there are many bourne *again* specific resources out there but I
only have experience with pure sh (actually Almquist* *sh)

Specific features that bash might give you that can't be expressed inside
ruby( if any) should be launched with the bash interpreter... though if you
get that far you may want to reevaluate your program.

You can get path and other info from ENV

of course ruby programs can be launched inside your #!/bin/sh scripts and as
I pointed out the other way around.

Also following the Unix philosophy: *Write programs that do one thing and do
it well. Write programs to work together. Write programs to handle text
streams, because that is a universal interface.*

And my philosophy: AUTOMATE EVERYTHING =)

happy hacking!
 
Y

Yu-Hsuan Lai

[Note: parts of this message were removed to make it a legal post.]

Yu,

As much as I liked using Ruby, what exactly are you looking to do with ruby
that you can't do with bash or ksh?
You also asked for a website resource. I feel this site is pretty
venerable:
http://www.shelldorado.com/

I'm sure there are many bourne *again* specific resources out there but I
only have experience with pure sh (actually Almquist* *sh)

Specific features that bash might give you that can't be expressed inside
ruby( if any) should be launched with the bash interpreter... though if you
get that far you may want to reevaluate your program.

You can get path and other info from ENV

of course ruby programs can be launched inside your #!/bin/sh scripts and
as
I pointed out the other way around.

Also following the Unix philosophy: *Write programs that do one thing and
do
it well. Write programs to work together. Write programs to handle text
streams, because that is a universal interface.*

And my philosophy: AUTOMATE EVERYTHING =)

happy hacking!

OH, sorry for my poor English.
Infact what I want to do is not "use ruby like shell script" but "use shell
in ruby".
For instant, I wonder if I can use "ls | grep" or "tar -xvf | grep" to get a
file list and store it in a ruby array, and handle them with io#gets.

I don't know what "back ticks" are.

Thank for all the replies.
 
J

Jesús Gabriel y Galán

OH, sorry for my poor English.
Infact what I want to do is not "use ruby like shell script" but "use she= ll
in ruby".
For instant, I wonder if I can use "ls | grep" or "tar -xvf | grep" to ge= t a
file list and store it in a ruby array, and handle them with io#gets.

I don't know what "back ticks" are.

You can execute shell commands via the following methods:

Kernel#system: system("ls | grep something")
Kernel#` `ls | grep something`
(this is the backtick)
%x: %x{ls | grep something}


irb(main):002:0> puts `ls`
applications
[...]
=3D> nil
irb(main):003:0> puts %x{ls}
applications
[...]
=3D> nil
irb(main):004:0> puts system("ls")
applications [...]
true
=3D> nil

Jesus.
 
R

Robert Klemme

OH, sorry for my poor English.
Infact what I want to do is not "use ruby like shell script" but "use shell
in ruby".
For instant, I wonder if I can use "ls | grep" or "tar -xvf | grep" to get a
file list and store it in a ruby array, and handle them with io#gets.

You do not need to call "ls" from Ruby scripts because there are Dir[],
Dir.glob and File.stat. In fact, this is much more efficient and robust
(semantics of "ls" changes dramatically between operating systems).

For the case with "tar" you can do

# 1.9
IO.popen ["tar", "xvf", file_name] do |io|
io.each do |line|
puts "found #{line}" if /\.rb$/ =~ line
end
end

# 1.8
IO.popen "tar xvf #{file_name}" do |io|
io.each do |line|
puts "found #{line}" if /\.rb$/ =~ line
end
end

You can even use grep:

io.grep /\.rb$/ do |match|
puts "found: #{match}"
end
I don't know what "back ticks" are.

output=`ls -l`

Kind regards

robert
 
S

Stu

OH, sorry for my poor English.
Infact what I want to do is not "use ruby like shell script" but "use shell
in ruby".
For instant, I wonder if I can use "ls | grep" or "tar -xvf | grep" to get a
file list and store it in a ruby array, and handle them with io#gets.

I don't know what "back ticks" are.

Thank for all the replies.

`backticks` are the keyboard symbol below the tilde.

backticks in a shell are the closest thing to object like programming
in the shell. The concept is part of what is known as shell
substitution and shell expansion.

The idea is that anything within the backticks are ran in a new shell
which inherits the environment and user created variables to the new
'sub' shell. of course the sub shell can spawn it's own shells and so
on.

In shell scripting the interpolation is done via ${ } which works the
same way as ruby's #{ }. This as well as the backticks follow the ruby
principle of least surprise( at least for shell coders).

If your looking for portability from unix to windows the Dir command
looks to be the best bet. Dir.glob("*") will return an array ready to
be parsed.

`ls` will return a string. you will need to parse it yourself or
create your own to_array via storing strings delimited on '/n'

If your just interested in programming for system automation on
unix/linux systems note that the commands from the gnu set may be a
bit different from *bsd and some commercial unixes. To keep everything
portable consider programming based on posix standards as to run on
every system with only ruby being the dependency.

if you need to capture stderr you can add 2>&1 inside the backticks.

Here is an example irb session:

ruby-1.9.2-head > sysout = `echo foo | sed s/foo/bar/g`
=> "bar\n"

ruby-1.9.2-head > $?
=> #<Process::Status: pid 5029 exit 0>

ruby-1.9.2-head > sysout = `echo foo | sed s/foo/bar/g 2>&1`
=> "bar\n"

ruby-1.9.2-head > $?
=> #<Process::Status: pid 5032 exit 0>

ruby-1.9.2-head > sysout = `echo foo | gsed s/foo/bar/g 2>&1`
=> "sh: gsed: command not found\n"

ruby-1.9.2-head > $?
=> #<Process::Status: pid 5035 exit 127>

ruby-1.9.2-head > sysout = `echo foo | gsed s/foo/bar/g`
sh: gsed: command not found
=> ""

ruby-1.9.2-head > $?
=> #<Process::Status: pid 5038 exit 127>

hope this helps
happy hacking!
 
O

Oliver Schad

Stu said:
lol I just figured out one way to make your ls command into an array.
in a single line.

x = `ls`.split

or

x = `echo *`.split

That's not a good idea. File names can contain white space, line breaks
and many more fuckup.

Regards
Oli
 
S

Stu

Right on. looks like String#split will take regular expressions.

This is one deals with white space issues by splitting on the newline
char \n in filenames:

x = `ls`.split(/\n/)
 
O

Oliver Schad

Stu said:
Right on. looks like String#split will take regular expressions.

This is one deals with white space issues by splitting on the newline
char \n in filenames:

x = `ls`.split(/\n/)

File names can contain new lines.

Regards
Oli
 
S

Stu

using tr (both in ruby and your shell) should help dealing with such
silliness both going in and also going out if such an extreme case
exists.

Oli what's your shell scripting example?
 
R

Robert Klemme

`backticks` are the keyboard symbol below the tilde.

No. At least not on my keyboard anyway. Remember that keyboard
layouts are localized as well. :)

Cheers

robert
 
R

Robert Klemme

using tr (both in ruby and your shell) should help dealing with such
silliness both going in and also going out if such an extreme case
exists.

Oli what's your shell scripting example?

This whole argument of yours just proves my point that the silliness
is actually using "ls" from a Ruby script when there are Dir.glob,
Dir[], Find.find, File.stat and the like in Ruby. Forking another
process for this is slow and error prone.

Kind regards

robert
 
O

Oliver Schad

Stu said:
using tr (both in ruby and your shell) should help dealing with such
silliness both going in and also going out if such an extreme case
exists.

Oli what's your shell scripting example?

None, you should use the system API to deal with directory and file
names.

Shell is crap for many things but good enough in many environments. But
if we talk about working solutions in general you should avoid the
shell.

The idiom "find -print0 | xargs -0" is a good example for the problems
with the shell. Shell hacker use it to circumvent the handling of file
names by the shell.

Regards
Oli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,697
Latest member
AugustNabo

Latest Threads

Top