"which in ruby": проверка, существует ли программа в $ PATH из ruby - PullRequest
75 голосов
/ 21 января 2010

мои скрипты сильно зависят от внешних программ и скриптов. Я должен быть уверен, что программа, которую мне нужно вызвать, существует. Вручную, я бы проверил это, используя 'which' в командной строке.

Есть ли эквивалент File.exists? для вещей в $PATH?

(да, я думаю, я мог бы разобрать %x[which scriptINeedToRun], но это не супер элегантно.

Спасибо! Янник


ОБНОВЛЕНИЕ: Вот решение, которое я сохранил:

 def command?(command)
       system("which #{ command} > /dev/null 2>&1")
 end

ОБНОВЛЕНИЕ 2: пришло несколько новых ответов - по крайней мере, некоторые из них предлагают лучшие решения.

Обновление 3: гем ptools добавил метод which для класса File.

Ответы [ 16 ]

1 голос
/ 02 января 2013

В Linux я использую:

exists = `which #{command}`.size.>(0)

К сожалению, which не является командой POSIX и поэтому ведет себя по-разному на Mac, BSD и т. Д. (То есть выдает ошибку, если команда не найдена). Может быть, идеальным решением было бы использовать

`command -v #{command}`.size.>(0)  # fails!: ruby can't access built-in functions

Но это не так, потому что ruby, похоже, не способен получить доступ к встроенным функциям. Но command -v будет POSIX способ сделать это.

1 голос
/ 13 ноября 2012

Решение на основе rogeriovl, но полная функция с проверкой выполнения, а не проверкой существования.

def command_exists?(command)
  ENV['PATH'].split(':').each {|folder| File.executable?(File.join(folder, command))}
end

Будет работать только для UNIX (Windows не использует двоеточие в качестве разделителя)

0 голосов
/ 12 января 2017
#####################################################
# add methods to see if there's an executable that's executable
#####################################################
class File
  class << self
    ###########################################
    # exists and executable
    ###########################################
    def cmd_executable?(cmd)
      !ENV['PATH'].split(':').select { |f| executable?(join(f, cmd[/^[^ \n\r]*/])) }.empty?
    end
  end
end
0 голосов
/ 02 октября 2015

для jruby, любое из решений, зависящих от mkmf, может не работать, так как имеет расширение C.

для jruby: простой способ проверить, является ли что-то исполняемым на пути:

main » unix_process = java.lang.Runtime.getRuntime().exec("git status")
=> #<Java::JavaLang::UNIXProcess:0x64fa1a79>
main » unix_process.exitValue()
=> 0
main »

если исполняемого файла нет, это вызовет ошибку времени выполнения, поэтому вы можете захотеть сделать это в блоке try / catch при фактическом использовании.

0 голосов
/ 30 июня 2010

Это трюк ответа rogeriopvl, который делает его кросс-платформенным:

require 'rbconfig'

def is_windows?
  Config::CONFIG["host_os"] =~ /mswin|mingw/
end

def exists_in_path?(file)
  entries = ENV['PATH'].split(is_windows? ? ";" : ":")
  entries.any? {|f| File.exists?("#{f}/#{file}")}
end
0 голосов
/ 21 января 2010

Не очень элегантно, но работает:).

<code>def cmdExists?(c)
  system(c + " > /dev/null")
  return false if $?.exitstatus == 127
  true
end

Предупреждение : Это НЕ рекомендуется, опасно совет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...