"Which in Ruby": Checking If Program Exists in $Path from Ruby

which in ruby : Checking if program exists in $PATH from ruby

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.

How to search an executable in $PATH in Ruby

There is find_executable

>> require 'mkmf'
=> true
>> find_executable 'ls'
checking for ls... yes
=> "/bin/ls"
>> find_executable 'no-such-command'
checking for no-such-command... no
=> nil

How to specify the location of the chromedriver binary

Solution 1 - Selenium::WebDriver::Chrome.driver_path=

There is a Selenium::WebDriver::Chrome.driver_path= method that allows specifying of the chromedriver binary:

require 'watir'

# Specify the driver path
chromedriver_path = File.join(File.absolute_path('../..', File.dirname(__FILE__)),"browsers","chromedriver.exe")
Selenium::WebDriver::Chrome.driver_path = chromedriver_path

# Start the browser as normal
b = Watir::Browser.new :chrome
b.goto 'www.google.com'
b.close

Solution 2 - Specify :driver_path during browser initialization

As an alternative, you can also specify the driver path when initializing the browser. This is a bit nicer in that you do not need to have Selenium code, but would be repetitive if you initialize the browser in different places.

# Determine the driver path
chromedriver_path = File.join(File.absolute_path('../..', File.dirname(__FILE__)),"browsers","chromedriver.exe")

# Initialize the browser with the driver path
browser = Watir::Browser.new :chrome, driver_path: chromedriver_path

Solution 3 - Update ENV['PATH']

When I had originally answered this question, for whatever reason, I had not been able to get the above solution to work. Setting the value did not appear to be used when Selenium-WebDriver started the driver in. While the first solution is the recommended approach, this is an alternative.

Another option is to programmatically add the desired directory to the path, which is stored in the ENV['PATH']. You can see in the Selenium::WebDriver::Platform that the binary is located by checking if the executable exists in any of the folders in the path (from version 2.44.0):

def find_binary(*binary_names)
paths = ENV['PATH'].split(File::PATH_SEPARATOR)
binary_names.map! { |n| "#{n}.exe" } if windows?

binary_names.each do |binary_name|
paths.each do |path|
exe = File.join(path, binary_name)
return exe if File.executable?(exe)
end
end

nil
end

To specify the folder that includes the binary, you simply need to change the ENV['PATH'] (to append the directory):

require 'watir'

# Determine the directory containing chromedriver.exe
chromedriver_directory = File.join(File.absolute_path('../..', File.dirname(__FILE__)),"browsers")

# Add that directory to the path
ENV['PATH'] = "#{ENV['PATH']}#{File::PATH_SEPARATOR}#{chromedriver_directory}"

# Start the browser as normal
b = Watir::Browser.new :chrome
b.goto 'www.google.com'
b.close

How can I run a ruby program as its own command?

Adding an alternative that I tend to prefer. Instead of balooning my PATH variable, I put a single folder such as ~/bin in my PATH. Then I create symlinks from here to any executables I have in odd locations. E.g. ln -s /path/to/myProgram.rb ~/bin/myProgram.rb

bash' : no such file or directory

You can check content of PATH variable by executing command $ echo $PATH

If you do not find /usr/bin in the output than you can append /usr/bin in PATH variable by executing command

$ export PATH=$PATH:/usr/bin

Jekyll - command not found

The easiest method of doing this is to use RVM. It manages Ruby and all its gems for you and it's easy to use. See this link for using it.

If you did not want to use that you will need to modify your PATH variables so it can find your gems. I have found this to be tedious and reverted to RVM, but here are the general steps.

You will need to find out where your gems are getting installed. If you did gem install ... the gems will be in ~/.gem/ruby/1.8/gems/bin, if you used sudo gem install ... the gems will be somewhere in /System/Library/Frameworks/Ruby.framework/Versions/1.8/Resources

You have to add this path to your PATH variable. Easiest way to do this is by running :
echo 'PATH=$PATH:above/path/to/gems' >> ~/.bash_profile

-bash is messed up?

When you set PATH to just one value, you lost all the other places to search, such as /bin and /usr/bin. Set your PATH incrementally:

export PATH=/new/place/bin:$PATH

You can be more elaborate than that, but that basic technique works.

Meantime, logout and login again - that will get you going most easily. Alternatively:

export PATH=$PATH:/bin:/usr/bin

Additionally, your first line was:

export PATH=$PATHEXECUTABLE DIRECTORY: /Users/zak/.rvm/gems/ruby-1.9.2-p0@rails3tutorial/bin

When you run export, it will export one or more variables, but the values must either be simple variable names, or must be variable assignments:

export SOMEVAR NOTHERVAR=new-value ...

The complaint -bash: export:DIRECTORY:': not a valid identifier` is telling you that 'DIRECTORY:' is not valid. It is not clear what you had in mind. And you got a similar complaint about /Users/zak/... not being an identifier.

You can set an environment variable for just one run of a command:

PATH=$EXECUTABLE_DIRECTORY:$PATH /Users/zak/bin/command

The environment of the command will include the value of PATH given; note, though, that the shell won't search for the command with that modified path.


...What I was trying to do was...

I'm not a user of either Ruby or Rails, but on my Mac (10.6.4), I can find:

Osiris-2 JL:  ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
Osiris-2 JL: rails -v
Rails 2.3.5
Osiris-2 JL: which ruby rails
/usr/bin/ruby
/usr/bin/rails
Osiris-2 JL:

So, on my machine, both Ruby and Rails are in /usr/bin. I don't have Heroku installed AFAIK (not on my PATH, anyway). Your first export clobbered PATH; the second one added your Ruby 1.9.2 directory to the empty PATH. Apparently, Heroku is installed somewhere else, or is not yet installed at all. You changed directory - a built-in operation that does not require a working PATH; you added the Ruby 1.9.2 directory to your PATH again (which didn't change anything usefully). Heroku is still not found. You echoed PATH (another built-in) - I'm not clear where the GEM: command not found message comes from. And the commands gem and heroko (sic) were not found. So, your first command set in train the problems.

Then you commented:

In terms of what I was trying to do, I was just trying to set-up my heroku account and got stuck when I tried to add my public ssh key. The heroko gem I had installed (thought) was not registering. That is when I read through the stackoverflow question referenced above that suggested my path was incorrect. I closed terminal and reopened. Running stuff like ruby -v outputs, but running rails -v does not. Is there something still to do? Why would rails -v not output?

Specifically on rails -v I get "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems.rb:827:in report_activate_error': Could not find RubyGem rails (>= 0) (Gem::LoadError) from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems.rb:261:inactivate' from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems.rb:68:in `gem' from /usr/bin/rails:18 "

This suggests that you have rails installed in /usr/bin (like I do), but the installation has been altered somehow so it is self-inconsistent. Either that or the messed up environment (PATH) is causing trouble. But usually, software can find its own bits'n'pieces, so it suggests there is something up. Part of the trouble may be that you're using a Ruby 1.9.2 program with some Ruby 1.8 software.

My personal policy is to leave o/s provided software strictly alone; I let the Mac updates take care of that. If I want my own version of something, I build it and install it under my control - I do this with Perl, sometimes with GCC, and with Git or SVN or Mercurial or other such software.

I would look at ensuring you have the Ruby 1.9.2 environment working fully, and worry about whether you need to update your Rails environment in parallel. I suspect that using Ruby 1.9.2 with Rails built for Ruby 1.8.x is causing some of the trouble - but I'm not certain of that.



Related Topics



Leave a reply



Submit