Miscellaneous Scripting Tasks

 
   

Ruby Way
By Hal Fulton
Slots : 1.0
Table of Contents
 


We have a few tidbits left over. We have decided to classify these as miscellaneous.

Piping into the Ruby Interpreter

Because the Ruby interpreter is a single-pass translator, it is possible to pipe code into it and have it executed. One conceivable purpose for this is to use Ruby for more complex tasks when you are required by circumstance to work in a traditional scripting language like Kornshell.

In Listing 8.6, for example, is a Kornshell script that uses Ruby (via a here document) to calculate the elapsed time in seconds between two dates. The Ruby program prints a single value to standard output, which is then captured by the ksh script.

Listing 8.6 Kornshell Script Invoking Ruby
 #!/usr/bin/ksh # Let ksh find the difference in seconds # between two dates using Ruby... export time1="2001-04-02 15:56:12" export time2="2001-12-08 12:03:19" cat <<EOF | ruby | read elapsed require "parsedate" time1 = ENV["time1"] time2 = ENV["time2"] args1 = ParseDate.parsedate(time1) args2 = ParseDate.parsedate(time2) args1 = args1[0..5] args2 = args2[0..5] t1 = Time.local(*args1) t2 = Time.local(*args2) diff = t2 - t1 puts diff EOF echo "Elapsed seconds = " $elapsed 

Note that the two input values in this case are passed as environment variables (which must be exported). The two lines that retrieve these values could also be coded in this way:

 

 time1="$time1"  # Embed the ksh variable directly time2="$time2"  #   into a string... 

However, the difficulties are obvious. It could get very confusing whether a certain string represents a ksh variable or a Ruby global variable, and there could be a host of problems with quoting and escaping.

It's also possible to use a Ruby one-liner with the -e option. Here's a little ksh script that reverses a string using Ruby:

 

 #!/usr/bin/ksh string="Francis Bacon" ruby -e "puts '$string'.reverse" | read reversed #  $reversed now has value "nocaB sicnarF" 

Unix geeks will note that awk has been used in a similar way since time immemorial.

Getting and Setting Exit Codes

The exit method will raise a SystemExit exception and ultimately return the specified exit code to the operating system (or to the calling entity). This is a Kernel method. There is also a method exit! that differs in two ways: It doesn't run the exit handlers before quitting, and the default return value is -1.

 

 # ... if (allOK)   exit      # Normally (0) else   exit!     # In a hurry (-1) end 

When a Ruby return code is retrieved by the operating system (for example, by doing echo $?), it is seen as the same integer specified in the code. When a subprocess exits and we use wait2 (or waitpid2) to examine the return code, we will find it left-shifted by eight bits. This is a POSIX quirk that Ruby has inherited.

 

 child = fork {  sleep 1; exit 3 } pid, code = Process.wait2        # [12554,768] status = code << 8               # 3 

Testing Whether a Program Is Running Interactively

A good way to determine whether a program is interactive is to test its standard input. The method isatty? (which historically means "is a teletype") will tell us whether the device is an interactive one as opposed to a disk file or socket.

 

 if STDIN.isatty?   puts "Hi! I see you're typing at"   puts "the keyboard..." end 

Determining the Current Platform or Operating System

If a program wants to know what operating system it's running on, it can access the global constant RUBY_PLATFORM. This will return a cryptic string (usually something similar to i386-cygwin or sparc-solaris2.7), telling the platform on which the Ruby interpreter was built.

Because we primarily use Unix variants (Solaris, AIX, Linux) and Windows variants (98, NT, 2000), we've found the following crude piece of code to be useful. It will distinguish between the Unix family and the Windows family of operating systems (unceremoniously lumping all others into other).

 

 def os_family   case RUBY_PLATFORM     when /ix/i, /ux/i, /gnu/i,          /sysv/i, /solaris/i,          /sunos/i, /bsd/i       "unix"     when /win/i, /ming/i       "windows"     else       "other"   end end 

This little set of regular expressions will correctly classify the vast majority of platforms. Of course, this is only a very clumsy way of determining how to handle OS dependencies. Even if you correctly determine the OS family, that might not always imply the availability (or absence) of any specific feature.

Using the Etc Module

The Etc module retrieves useful information from the /etc/passwd and /etc/group files. Obviously, this is only useful in a Unix environment.

The getlogin method will return the login name of the user. If it fails, getpwuid might work (taking an optional parameter, which is the uid).

 

 myself = getlogin             # hal9000 myname = getpwuid(2001).name  # hal9000 # Without a parameter, getpwuid calls # getuid internally... me2 = getpwuid.name           # hal9000 

The getpwnam method returns a passwd struct, which contains relevant entries such as name, dir (home directory), shell (login shell), and others.

 

 rootshell = getpwnam("root").shell   # /sbin/sh 

At the group level, getgrgid or getgrnam behave similarly. They will return a group struct consisting of group name, group passwd, and so on.

The iterator passwd will iterate over all entries in the /etc/passwd file. Each entry passed into the block is a passwd struct.

 

 all_users = [] passwd {  |entry| all_users << entry.name } 

There is an analogous iterator group for group entries.

Libraries and Utilities You Should Know About

Several other items are worth a brief mention. As always, see the Ruby Application Archive for the latest and greatest tools.

For Tcl fans, the standard Ruby distribution has a library called expect.rb, which acts similar to Tcl's expect extension. See the README for limited documentation.

For those needing to do error logging from Ruby, there is a syslog extension. It is a wrapper for the Unix function of the same name.

Minero Aoki has created several tools, notably setup.rb (which aids in installing Ruby scripts and libraries) and TMail, which aids in handling mail messages (including some MIME support). Another mail library is Michael Neumann's mbox, which reads and writes the Unix mailbox format.


   

 

 



The Ruby Way
The Ruby Way, Second Edition: Solutions and Techniques in Ruby Programming (2nd Edition)
ISBN: 0672328844
EAN: 2147483647
Year: 2000
Pages: 119
Authors: Hal Fulton

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net