Functional Command-Line Chaining

I recently had to write a bit of code that would take a MySQL dump and load it into a database on request. Upon testing it, I found that all the backups that were already stored that I could use were .tar.gz files, and all of the new ones I’d just created were .sql.bz2 files. I wrote the following code to take a file in any of these formats and construct a command to output its contents to stdout.

1
2
3
4
5
6
7
8
9
10
11
12
13

commands = some_file.split(".")[1..-1].reverse.map do |ext|
  case ext
    when "gz" then "gzcat -"
    when "bz2" then "bzcat -"
    when "bzip2" then "bzcat -"
    when "tar" then "tar -Ox --"
    when "tgz" then "tar -Ozx --"
    when "tbz" then "tar -Ojx --"
    else "cat"
  end
end
command = "cat #{dump_file} | " + commands.join(" | ");

Obviously this could be expanded with different file types, as long as there’s a command-line utility that will accept standard input and expand to standard output.


About this entry