“which in Ruby”: checking if program exists in $PATH from Ruby

path, ruby, unix

Solution

True cross-platform solution, works properly on Windows:

# Cross-platform way of finding an executable in the $PATH.
#
#   which('ruby') #=> /usr/bin/ruby
def which(cmd)
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
    exts.each do |ext|
      exe = File.join(path, "#{cmd}#{ext}")
      return exe if File.executable?(exe) && !File.directory?(exe)
    end
  end
  nil
end

This doesn't use host OS sniffing, and respects $PATHEXT which lists valid file extensions for executables on Windows.

Shelling out to `which` works on many systems but not all.

Problem

My scripts rely heavily on external programs and scripts. I need to be sure that a program I need to call exists. Manually, I’d check this using `which` in the command line. Is there an equivalent to `File.exist?` for things in `$PATH`? (Yes, I guess I could parse the result of `%x[which scriptINeedToRun]`, but that’s not super elegant.)

Original source