module UnixUtils

Constants

BUFSIZE
VERSION

Public Class Methods

_spawn(argv, input, output, error) click to toggle source
# File lib/unix_utils.rb, line 293
def self._spawn(argv, input, output, error)
  # lifted from posix-spawn
  # https://github.com/rtomayko/posix-spawn/blob/master/lib/posix/spawn/child.rb
  Open3.popen3(*argv) do |stdin, stdout, stderr|
    readers = [stdout, stderr]
    if RUBY_DESCRIPTION =~ /jruby 1.7.0/
      readers.delete stderr
    end
    writers = if input
      [stdin]
    else
      stdin.close
      []
    end
    while readers.any? or writers.any?
      ready = IO.select(readers, writers, readers + writers)
      # write to stdin stream
      ready[1].each do |fd|
        begin
          boom = nil
          size = fd.write input.read(BUFSIZE)
        rescue Errno::EPIPE => boom
        rescue Errno::EAGAIN, Errno::EINTR
        end
        if boom || size < BUFSIZE
          stdin.close
          input.close
          writers.delete stdin
        end
      end
      # read from stdout and stderr streams
      ready[0].each do |fd|
        buf = (fd == stdout) ? output : error
        if fd.eof?
          readers.delete fd
          fd.close
        else
          begin
            buf << fd.readpartial(BUFSIZE)
          rescue Errno::EAGAIN, Errno::EINTR
          end
        end
      end
    end
    # thanks @tmm1 and @rtomayko for showing how it's done!
  end
end
awk(infile, *expr) click to toggle source

# File lib/unix_utils.rb, line 163
def self.awk(infile, *expr)
  infile = File.expand_path infile
  outfile = tmp_path infile
  bin = available?('gawk') ? 'gawk' : 'awk'
  argv = [bin, expr, infile].flatten
  spawn argv, :write_to => outfile
  outfile
end
bunzip2(infile) click to toggle source
# File lib/unix_utils.rb, line 119
def self.bunzip2(infile)
  infile = File.expand_path infile
  outfile = tmp_path infile
  argv = ['bunzip2', '--stdout', infile]
  spawn argv, :write_to => outfile
  outfile
end
bzip2(infile) click to toggle source

# File lib/unix_utils.rb, line 129
def self.bzip2(infile)
  infile = File.expand_path infile
  outfile = tmp_path infile, '.bz2'
  argv = ['bzip2', '--keep', '--stdout', infile]
  spawn argv, :write_to => outfile
  outfile
end
curl(url, form_data = nil) click to toggle source
# File lib/unix_utils.rb, line 13
def self.curl(url, form_data = nil)
  outfile = tmp_path url
  if url.start_with?('file://') or not url.include?('://')
    # deal with local files
    infile = File.expand_path url.sub('file://', '')
    unless File.readable?(infile)
      raise "[unix_utils] #{url.inspect} does not exist or is not readable on the local filesystem."
    end
    FileUtils.cp infile, outfile
    return outfile
  end
  uri = URI.parse url
  argv = [ 'curl', '--location', '--show-error', '--silent', '--compressed', '--header', 'Expect: ' ]
  if form_data
    argv += [ '--data', form_data ]
  end
  argv += [ uri.to_s, '--output', outfile ]
  spawn argv
  outfile
end
cut(infile, character_positions) click to toggle source

specify character_positions as a string like “3-5” or “3,9-10”

# File lib/unix_utils.rb, line 226
def self.cut(infile, character_positions)
  infile = File.expand_path infile
  outfile = tmp_path infile
  argv = ['cut', '-c', character_positions, infile]
  spawn argv, :write_to => outfile
  outfile
end
dos2unix(infile) click to toggle source
# File lib/unix_utils.rb, line 190
def self.dos2unix(infile)
  infile = File.expand_path infile
  if available?('gawk') or available?('awk')
    awk infile, '{ sub(/\r/, ""); printf("%s\n", $0) }'
  else
    perl infile, 's/\r\n|\n|\r/\n/g'
  end
end
du(srcdir) click to toggle source
# File lib/unix_utils.rb, line 77
def self.du(srcdir)
  srcdir = File.expand_path srcdir
  argv = ['du', '-sk', srcdir]
  stdout = spawn argv
  stdout.strip.split(/\s+/).first.to_i
end
gunzip(infile) click to toggle source
# File lib/unix_utils.rb, line 111
def self.gunzip(infile)
  infile = File.expand_path infile
  outfile = tmp_path infile
  argv = ['gunzip', '--stdout', infile]
  spawn argv, :write_to => outfile
  outfile
end
gzip(infile) click to toggle source
# File lib/unix_utils.rb, line 153
def self.gzip(infile)
  infile = File.expand_path infile
  outfile = tmp_path infile, '.gz'
  argv = ['gzip', '--stdout', infile]
  spawn argv, :write_to => outfile
  outfile
end
head(infile, lines) click to toggle source
# File lib/unix_utils.rb, line 217
def self.head(infile, lines)
  infile = File.expand_path infile
  outfile = tmp_path infile
  argv = ['head', '-n', lines.to_s, infile]
  spawn argv, :write_to => outfile
  outfile
end
iconv(infile, to, from) click to toggle source
# File lib/unix_utils.rb, line 234
def self.iconv(infile, to, from)
  infile = File.expand_path infile
  outfile = tmp_path infile
  argv = ['iconv', '-c', '-t', to, '-f', from, infile]
  spawn argv, :write_to => outfile
  outfile
end
md5sum(infile) click to toggle source
# File lib/unix_utils.rb, line 64
def self.md5sum(infile)
  infile = File.expand_path infile
  if available?('md5sum')
    argv = ['md5sum', '--binary', infile]
    stdout = spawn argv
    stdout.strip.split(' ').first
  else
    argv = ['openssl', 'dgst', '-md5', infile]
    stdout = spawn argv
    stdout.strip.split(' ').last
  end
end
method_missing(method_id, *args) click to toggle source
Calls superclass method
# File lib/unix_utils.rb, line 341
def self.method_missing(method_id, *args)
  base_method_id = method_id.to_s.chomp('_s')
  if respond_to?(base_method_id)
    begin
      outfile = send(*([base_method_id]+args))
      File.read outfile
    ensure
      FileUtils.rm_f outfile
    end
  else
    super
  end
end
perl(infile, *expr) click to toggle source

Yes, this is a very limited use of perl.

# File lib/unix_utils.rb, line 173
def self.perl(infile, *expr)
  infile = File.expand_path infile
  outfile = tmp_path infile
  argv = [ 'perl', expr.map { |e| ['-pe', e] }, infile ].flatten
  spawn argv, :write_to => outfile
  outfile
end
sed(infile, *expr) click to toggle source

POSIX sed, whether it's provided by sed or gsed

# File lib/unix_utils.rb, line 200
def self.sed(infile, *expr)
  infile = File.expand_path infile
  outfile = tmp_path infile
  bin = available?('sed') ? 'sed' : ['gsed', '--posix']
  argv = [ bin, expr.map { |e| ['-e', e] }, infile ].flatten
  spawn argv, :write_to => outfile
  outfile
end
shasum(infile, algorithm) click to toggle source
# File lib/unix_utils.rb, line 44
def self.shasum(infile, algorithm)
  infile = File.expand_path infile
  if available?('shasum')
    argv = ['shasum', '--binary', '-a', algorithm.to_s, infile]
    stdout = spawn argv
    stdout.strip.split(' ').first
  else
    argv = ['openssl', 'dgst', "-sha#{algorithm}", infile]
    stdout = spawn argv
    stdout.strip.split(' ').last
  end
end
tail(infile, lines) click to toggle source
# File lib/unix_utils.rb, line 209
def self.tail(infile, lines)
  infile = File.expand_path infile
  outfile = tmp_path infile
  argv = ['tail', '-n', lines.to_s, infile]
  spawn argv, :write_to => outfile
  outfile
end
tar(srcdir) click to toggle source
# File lib/unix_utils.rb, line 137
def self.tar(srcdir)
  srcdir = File.expand_path srcdir
  outfile = tmp_path srcdir, '.tar'
  argv = ['tar', '-cf', outfile, '-C', srcdir, '.']
  spawn argv
  outfile
end
unix2dos(infile) click to toggle source
# File lib/unix_utils.rb, line 181
def self.unix2dos(infile)
  infile = File.expand_path infile
  if available?('gawk') or available?('awk')
    awk infile, '{ sub(/\r/, ""); printf("%s\r\n", $0) }'
  else
    perl infile, 's/\r\n|\n|\r/\r\n/g'
  end
end
untar(infile) click to toggle source
# File lib/unix_utils.rb, line 102
def self.untar(infile)
  infile = File.expand_path infile
  destdir = tmp_path infile
  FileUtils.mkdir destdir
  argv = ['tar', '-xf', infile, '-C', destdir]
  spawn argv
  destdir
end
unzip(infile) click to toggle source

# File lib/unix_utils.rb, line 93
def self.unzip(infile)
  infile = File.expand_path infile
  destdir = tmp_path infile
  FileUtils.mkdir destdir
  argv = ['unzip', '-qq', '-n', infile, '-d', destdir]
  spawn argv
  destdir
end
wc(infile) click to toggle source
# File lib/unix_utils.rb, line 84
def self.wc(infile)
  infile = File.expand_path infile
  argv = ['wc', infile]
  stdout = spawn argv
  stdout.strip.split(/\s+/)[0..2].map { |s| s.to_i }
end
zip(srcdir) click to toggle source
# File lib/unix_utils.rb, line 145
def self.zip(srcdir)
  srcdir = File.expand_path srcdir
  outfile = tmp_path srcdir, '.zip'
  argv = ['zip', '-rq', outfile, '.']
  spawn argv, :chdir => srcdir
  outfile
end