Can ruby replace bash scripts for linux script

hi,

I need to develop some backup scripts for my linux box. I’m ok with
Ruby but havn’t done bash scripts before.

Is ruby up to replacing bash shell scripts for this? (eg calling
commands, eg rsynch, getting responses etc?

Thanks

On Jul 11, 2008, at 9:54 PM, Greg H. wrote:

hi,

I need to develop some backup scripts for my linux box. I’m ok with
Ruby but havn’t done bash scripts before.

Is ruby up to replacing bash shell scripts for this? (eg calling
commands, eg rsynch, getting responses etc?

Thanks

yes. astoundingly.

a @ http://codeforpeople.com/

Greg H. wrote:

hi,

I need to develop some backup scripts for my linux box. I’m ok with
Ruby but havn’t done bash scripts before.

Bash is a different kind of language, both because it’s more devoted to
handling native unix executables, but also because it’s a more primitive
and older language devoted to doing things in ways they needed to be
done before the present price/cost of resources.

There are a lot of things you can do much more efficiently in Bash, and
in far fewer lines. Also, in Sysadmin land, you may find more of the
people managing your production boxes will know Bash than Ruby.
Probably far more. In my shop, practically everyone is still refusing
to use Ruby and they want me to write anything I can in Bash, when it’s
at all practical. To a certain extent I think this kind of request has
reasonable roots and should be taken into account.

That all being said, and despite the fact that Ruby programs can be
longer, Ruby programs can be much more readable, IMHO, than Bash
scripts, especially when the complexity of the program increases beyond
a few hundred lines of code. Now I have several Bash scripts that
include libraries of Bash functions and the entire things are well over
a thousand lines, and these are still reasonable pieces of software.
Most things that size make me think of Ruby as the best long term,
maintainable way to program. The reasons, again IMHO, include:

  1. A lot of general facilities which allow for clean solutions
    that would be ugly in Bash. For instance, I recently ran into a
    Bash script that had sequences of over 10 sed commands to decode
    %nn embedded strings from an HTTP query string. Ruby has native
    methods for this that you can depend upon. When you write your
    own, thats gonna be delicate code subject to getting trashed in
    some quick vi edit.

  2. Class organization, which I like to do when the programmed
    activity is best illustrated with that kind of organization, is
    nicely formalized in Ruby, and requires thought and jury-rigging
    in Bash.

  3. Loops are very flexible in Ruby. On the other hand, in Bash
    they may sometimes be more concise.

  4. Structures in Ruby are generally clearer and more readable:

if [[ x != 'y' ]]; then
  somefunction $arg1 $arg2
else
  echo "ERROR:  blek $myevidence"
  exit 1
fi

vs Ruby

if x != 'y' then
  somemethod(arg1,arg2)
else
  raise Exception, "ERROR:  blek #{myevidence}"
end

The difference may not send you, but the extra little tick marks
and such can be a big time cost when it comes to debugging and
maintenance. Interpolation, as evidenced above, actually uses
more, but is more clear and flexible, and is always the same.

Is ruby up to replacing bash shell scripts for this? (eg calling
commands, eg rsynch, getting responses etc?

Yes, but it’s up to you whether you want to spend the time. I have a
class I call FlatAccess which has methods like:

MYUSER=myusername
SUDOPART = “sudo -u #{MYUSER}”

def FlatAccess.sudo(shellcmd)
#{SUDOPART} #{shellcmd}
end

But of course you can just state the command directly like:
result = sudo -u myusername #{shellcmd}
—snip—

Now all that being said, there’s also something called capistrano that
does this kind of thing in Ruby for you, so if you’re doing that a lot,
it is worth looking into capistrano. Perhaps I’ll do that myself some
time soon…

There are a lot of other facilities in native Ruby to do system stuff,
so the more encompassing answer is: yes.

One thing I did recently which was interesting was to use pipes and
threads to collect output from stderr and stdout at the same time from a
shell execution of curl.

xc

  1. Loops are very flexible in Ruby. On the other hand, in Bash
    they may sometimes be more concise.

loop {}

But I am curious what you mean specifically in bash. :slight_smile:

To be honest, maybe except for speed, I see 0 reason to use
bash scripts preferred over ruby scripts.

tks xc,

Given I’m a hobbiest programmer I think I’ll try to write my linux
backup script in Ruby then. I don’t get that much time so sticking to
Ruby for me would be great.

BTW: I’d also posted on the capistrano (which I use) group re this. I
guess if I’m using rsynch however it’ll handle ssh under the bonnet
(cf cap’s libraries for ssh etc)

Are there any tips re calling unix commands & receiving responses in
ruby?

thanks

Greg H. wrote:

Is ruby up to replacing bash shell scripts for this? (eg calling
commands, eg rsynch, getting responses etc?

Yes, but this is exactly what Perl was developed for originally: a
scripting language superior to csh, awk, etc. Ruby has its roots in Perl
syntax, but whether you need its object orientation for system scripting
is debateable.

On WinXP it seems that Ruby’s start-up time is much slower than Perl’s.
I haven’t used Ruby much on Linux but I suspect that Perl may be faster
there too, given that Perl has been well tuned for speed over the years.

Dave

On Jul 12, 4:59 pm, Dave B. [email protected] wrote:

I haven’t used Ruby much on Linux but I suspect that Perl may be faster
there too, given that Perl has been well tuned for speed over the years.

Dave

Posted viahttp://www.ruby-forum.com/.

i.using back-quotes is the easiest way to get the output of Unix
commands from Ruby.

response = ls

response will be a string object now containing the result of the ‘ls’
command.

ii. x = IO.popen(“ls”)
response = IO.read

read documentation for popen, it has options for reading Unix
program’s STDOUT & STDERR separately.

iii. system(“ls”) - this call can be used to run Unix commands. but
their outputs cannot be captured.

Dave B. wrote:

On WinXP it seems that Ruby’s start-up time is much slower than Perl’s.
I haven’t used Ruby much on Linux but I suspect that Perl may be faster
there too, given that Perl has been well tuned for speed over the years.

How much of that delay is due to gems? Try setting RUBYOPT="" and
running ruby.

You may want to take a glance at André Ben Hamou, Practical Ruby for
System Administration, 2007, if your neighbourhood library happens to
have it.

It is helping me a lot in my Ruby learning process. It almost convinced
me that Ruby might be able to replace Perl for administration tasks
(huge amount of available good Perl code and documentation aside).

But you’ll still need a solid understanding of administration tasks on
your system, hence a good command of its command line interpreter.

Kind regards, Ömer.

Marc H. wrote:

  1. Loops are very flexible in Ruby. On the other hand, in Bash
    they may sometimes be more concise.

loop {}

for d in $(ls $MYDIR/*)
do
echo “trace: $d”
done

versus

Dir["#{MYDIR}/*"].each do |d|
puts “trace: $d”
end

So, given the difference isn’t much, I’d assert the first one is a
little clearer. There are a lot of such examples.

I think another aspect of where I’m at is that everybody knows Bash, and
I did allude to that before. If you know people are gonna have to hack
stuff, and your in a business, you try to provide the best environment
for them to do so.

I can certainly see it being reasonable to do practically everything in
Ruby, however, and I wouldn’t mind doing that if the work environment
made it a reasonable way to go.

xc

versus

Dir["#{MYDIR}/*"].each do |d|
puts “trace: $d”
end

Why use 3 lines?

Dir["#{MYDIR}/*"].each { |d| p 'trace: '+d }

Also the two versions are not the same IMO because
ruby applies .each on an array.

I didn’t know you meant an iteration, I really thought
you referred to a loop {} :slight_smile:

Maybe we should compare longer versions to get a
clear picture too including methods/functions

Also bash-scripts are a DSL for bash so if they
are allowed to use a DSL, ruby should be too :slight_smile:

So, given the difference isn’t much, I’d assert the first one is a
little clearer. There are a lot of such examples.

I don’t really see that bash is clearer here.

In a typical shell scripts I see a lot of conditionals applied

if [ “$os” != “SunOS” ]
then
zeige=“echo -e”
else
zeige=“echo”
fi

And to be honest I see no point in being more readable.

I think another aspect of where I’m at is that everybody knows Bash, and
I did allude to that before.

People new to Linux are not. I also challenge the notion that everybody
knows
bash == everybody likes to write bash, or even knows bash/shell scripts.

you try to provide the best environment for them to do so.

Sure. I give them ruby :slight_smile:
Linux distributions love shell scripts. It is one reason why they fail
to
grow - these shell scripts are hardly maintained by other people.
They are ugly, sometimes buggy, provide no real additional
value … and what is one supposed to use them for on windows
anyway?

Enter Ruby.

I can certainly see it being reasonable to do practically everything in
Ruby, however, and I wouldn’t mind doing that if the work environment
made it a reasonable way to go.

Well, I don’t say to abandon bash scripts. :slight_smile: They have many use cases,
one that comes to my mind if ruby is not available or broken (i manage
to break everything… )

I just think that people need to stop relying so much on shell scripts
as
they did the last 20 years. Shell scripts didnt revolutionize the world,
and they won’t. They can provide task, but so can ruby.

And I think it is simply better to look for new ways to solve problems
rather than sticking to concepts which won’t change much anymore.

Anyway, hopefully we convinced Greg H. to stick to the
solution he prefers, so at least ruby will get a decent chance :wink:

Hi,

At Sun, 13 Jul 2008 04:27:05 +0900,
Xeno C. wrote in [ruby-talk:307982]:

So, given the difference isn’t much, I’d assert the first one is a
little clearer. There are a lot of such examples.

Note that you may get unexpected results if there are files
contain space or shell meta-characters. Bourne familly shells
automatically split strings into a list with $IFS. It’s
sometimes convenient but sometimes a pitfall.

On 13/07/2008, ara.t.howard [email protected] wrote:

Dir["#{MYDIR}/*"].each do |d|
puts “trace: $d”
end

first one does not work, the second does.

for d in $MYDIR/*
do
echo $d
done

This kind of file and directory processing can be very consise in a
shell (bash, ksh or zsh or name it; this type of constructs can be
used on the command line too)
For short commands it can’t be beaten by higher level scripts. But
the point where it is smarter to use perl or ruby is quickly
reached…

Ruud

On Jul 12, 2008, at 1:27 PM, Xeno C. wrote:

for d in $(ls $MYDIR/*)
do
echo “trace: $d”
done

versus

Dir["#{MYDIR}/*"].each do |d|
puts “trace: $d”
end

first one does not work, the second does.

a @ http://codeforpeople.com/

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs