Ruby development for system administrators
Koen Vervloesem doesn’t like shell scripts that are difficult to maintain, therefore he uses Ruby for his sysadmin tasks. Do the same with his four-page guide…
In our previous scripts, we already used the method File.open to read a file. We can also create a new file and write text to it:
file = File.new(“temp.txt”, “w”) file.puts(“foobar”) file.close
We can also do a lot with file metadata:
puts File.open(“temp.txt”).atime File.open(“temp.txt”).chmod(0600) File.open(“temp.txt”).chown(1000, 1000)
But most of the interesting methods are class methods, which take the filename as an argument…
File.dirname(“/home/koan/temp.txt”) File.basename(“/home/koan/temp.txt”) File.size(“/home/koan/temp.txt”) File.delete(“/home/koan/temp.txt”) File.exists?(“/home/koan/temp.txt”) File.directory?(“/home/koan/temp.txt”) File.executable?(“/home/koan/temp.txt”)
There’s also a Dir class for directories, a module FileUtils for copying, moving, removing files and so on, and a module Find to make it easier to recursively search for files under a directory. We’ll illustrate this in a script that searches for backup files (*~) in a directory (recursively) and zips them for archival. The original files can then be deleted safely, but we leave this as an exercise to the reader.
#!/usr/bin/env ruby
require ‘rubygems’
gem ‘rubyzip’
require ‘find’
require ‘zip/zip’
directory = ARGV[0]
pattern = “*~”
Zip::ZipFile.open(“backup.zip”, Zip::ZipFile::CREATE) do |zipfile|
Find.find(directory) do |path|
filename = File.basename(path)
if File.directory?(path)
if filename == ‘.’ or filename == ‘..’
Find.prune
end
else
if File.fnmatch(pattern, filename)
puts path
zipfile.add(path.sub(directory, “”), path)
end
end
end
end
Here we see another way to install a non-standard Ruby library: using Ruby gems, the programming language’s own package manager. The directory that we want to search in is the first argument to the script, and the search pattern is ‘*~’. Then we create a zip file and start searching in the directory with the Find.find method.
This will iterate through each file recursively. If the file is ‘.’ (the current directory) or ‘..’ (the parent directory), we don’t look any further into this directory. If it’s another directory we don’t do anything with the directory itself, which means that next it’s the turn of the files in this directory. In the other case (the current file is a regular file), the filename is matched to the pattern – if it matches, the file is added to the zip file, with its relative path to the directory we searched in as the zip index.
Advanced usage
Of course, Ruby is not the holy grail for sysadmins. There are a lot of cases where Perl or even shell scripts are better. For example, the number of Ruby libraries can’t beat the breadth of Perl modules in CPAN. So if your task requires such functionality, it’s probably better to use Perl. However, Ruby catches on quickly, and recently some powerful system administration tools have been written in Ruby, such as the configuration management tool Puppet, which we’ll talk about in another article.
The examples we have shown are of course rather basic, but you get the picture. If you want to do some serious sysadmin tasks in Ruby scripts, you have to take care of error handling and a robust command-line interface instead of just using ARGV[0]. The GetoptLong module can parse the command’s arguments and options in a structured way.
When your Ruby sysadmin scripts begin to grow in complexity, it’s also a good idea to restructure them as Rake tasks. Rake originated as a simple Ruby build program with capabilities similar to the UNIX make command, but it’s also very usable to do deployment tasks or migrate database schemas.
Click here to see what else was in issue 89 of Linux User & Developer…















The guide is quite informative.
But since your site engine does not support proper code formatting, examples require tweaking before use.
Or Ruby’s really capable of interpreting the WinWord-style single quotes – “require ‘csv’”?
Nice introduction, the said “when men were men….” is forgotten, but the tools help more than “prestige”. Thanks for this article.
@Dummy00001 Ruby can use single or double quoted strings. Double quoted strings give you some extra functionality when it comes to string interpolation but it is a fairly standard Ruby practice to use single quoted otherwise.