I would like to change the name of the ruby process that gets displayed in the linux/unix top command. I have tried the
$0='miname'
approach but it only works with the ps command and in top the process keeps getting displayed as "ruby"
Dave Thomas had an interesting post on doing this in rails. There's nothing rails specific about the actual process name change code. He uses the $0='name' approach. When I followed his steps the name was changed in ps and top.
In the post he suggests using the c keyboard command if your version of top doesn't show the short version of the command by default.
Ruby 2.1 introduced a Process.setproctitle method for this purpose:
Process.setproctitle("My new title")
I don't think Ruby has the facility builtin (setproctitle(3)). You should probably try to look at ruby-ffi and create the interface to setproctitle(3).
EDIT: I know you have your answer but I want to show you some code to use ffi:
require "ffi"
#
module LibC
extend FFI::Library
attach_function :setproctitle, [:string, :varargs], :void
end
LibC.setproctitle("Ruby: executing %s", :string, $0)
Does not work on OS X because setproctitle(3) does not exist, works on FreeBSD.
The $0 = 'Foo' method works -- but many versions of top will require you to toggle command-line mode on with 'c'. We this very method here with rails and CentOS. Works a treat
I had a similar problem, updated the technique from the Dave Thomas post a little by putting it in a rack middleware, rather than the before/after pattern.
Put this in lib/rack/set_process_title.rb:
# Set the process title to the URI being processed
#- useful for debugging slow requests or those that get stuck
class Rack::SetProcessTitle
def initialize(app)
#app = app
end
def call(env)
$0 = env['REQUEST_URI'][0..80]
#status, #headers, #response = #app.call(env)
$0 = env['REQUEST_URI'][0..80] + '*'
[#status, #headers, #response]
end
end
... and this goes at the end of config/environment.rb:
Rails.configuration.middleware.insert_after Rack::Lock, Rack::SetProcessTitle
More words in the blog post: http://blog.actbluetech.com/2011/06/set-your-process-name-in-top-and-ps.html
I know Keltia already posted something very similar, but Linux doesn't have setproctitle(3).
Linux has had this functionality in prctl() since version 2.6.9.
I used Fiddle/DL since they are included by default with Ruby.
require("fiddle")
def set_process_name_linux(name)
Fiddle::Function.new(
Fiddle::Handle["prctl".freeze], [
Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP,
Fiddle::TYPE_LONG, Fiddle::TYPE_LONG,
Fiddle::TYPE_LONG
], Fiddle::TYPE_INT
).call(15, name, 0, 0, 0)
end
def set_process_name_unknown(name)
warn("No implementation for this OS.".freeze)
end
def set_process_name(name)
case RUBY_PLATFORM.split("-".freeze)[1]
when "linux".freeze
set_process_name_linux(name)
else
set_process_name_unknown(name)
end
end
From #jessehz answer, following code work perfect on my linux X86_64.
Ruby 1.9.3, 2.0, 2.1, 2.2, 2.3 is tested.
It will change the output in ps top command.
It can be kill or signal with pkill, pgrep, killall.
Perfect!
def set_process_name_linux(name)
handle = defined?(DL::Handle) ? DL::Handle : Fiddle::Handle
Fiddle::Function.new(
handle['prctl'.freeze], [
Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP,
Fiddle::TYPE_LONG, Fiddle::TYPE_LONG,
Fiddle::TYPE_LONG
], Fiddle::TYPE_INT
).call(15, name, 0, 0, 0)
$PROGRAM_NAME = name
end
set_process_name_linux('dummy')
Related
I would like to know whether I can get source code a method on the fly, and whether I can get which file is this method in.
like
A.new.method(:a).SOURCE_CODE
A.new.method(:a).FILE
Use source_location:
class A
def foo
end
end
file, line = A.instance_method(:foo).source_location
# or
file, line = A.new.method(:foo).source_location
puts "Method foo is defined in #{file}, line #{line}"
# => "Method foo is defined in temp.rb, line 2"
Note that for builtin methods, source_location returns nil. If want to check out the C source code (have fun!), you'll have to look for the right C file (they're more or less organized by class) and find the rb_define_method for the method (towards the end of the file).
In Ruby 1.8 this method does not exist, but you can use this gem.
None of the answers so far show how to display the source code of a method on the fly...
It's actually very easy if you use the awesome 'method_source' gem by John Mair (the maker of Pry):
The method has to be implemented in Ruby (not C), and has to be loaded from a file (not irb).
Here's an example displaying the method source code in the Rails console with method_source:
$ rails console
> require 'method_source'
> I18n::Backend::Simple.instance_method(:lookup).source.display
def lookup(locale, key, scope = [], options = {})
init_translations unless initialized?
keys = I18n.normalize_keys(locale, key, scope, options[:separator])
keys.inject(translations) do |result, _key|
_key = _key.to_sym
return nil unless result.is_a?(Hash) && result.has_key?(_key)
result = result[_key]
result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
result
end
end
=> nil
See also:
https://rubygems.org/gems/method_source
https://github.com/banister/method_source
http://banisterfiend.wordpress.com/
Here is how to print out the source code from ruby:
puts File.read(OBJECT_TO_GET.method(:METHOD_FROM).source_location[0])
Without dependencies
method = SomeConstant.method(:some_method_name)
file_path, line = method.source_location
# puts 10 lines start from the method define
IO.readlines(file_path)[line-1, 10]
If you want use this more conveniently, your can open the Method class:
# ~/.irbrc
class Method
def source(limit=10)
file, line = source_location
if file && line
IO.readlines(file)[line-1,limit]
else
nil
end
end
end
And then just call method.source
With Pry you can use the show-method to view a method source, and you can even see some ruby c source code with pry-doc installed, according pry's doc in codde-browing
Note that we can also view C methods (from Ruby Core) using the
pry-doc plugin; we also show off the alternate syntax for show-method:
pry(main)> show-method Array#select
From: array.c in Ruby Core (C Method):
Number of lines: 15
static VALUE
rb_ary_select(VALUE ary)
{
VALUE result;
long i;
RETURN_ENUMERATOR(ary, 0, 0);
result = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
rb_ary_push(result, rb_ary_elt(ary, i));
}
}
return result;
}
I created the "ri_for" gem for this purpose
>> require 'ri_for'
>> A.ri_for :foo
... outputs the source (and location, if you're on 1.9).
GL.
-r
Internal methods don't have source or source location (e.g. Integer#to_s)
require 'method_source'
User.method(:last).source
User.method(:last).source_location
I had to implement a similar feature (grab the source of a block) as part of Wrong and you can see how (and maybe even reuse the code) in chunk.rb (which relies on Ryan Davis' RubyParser as well as some pretty funny source file glomming code). You'd have to modify it to use Method#source_location and maybe tweak some other things so it does or doesn't include the def.
BTW I think Rubinius has this feature built in. For some reason it's been left out of MRI (the standard Ruby implementation), hence this hack.
Oooh, I like some of the stuff in method_source! Like using eval to tell if an expression is valid (and keep glomming source lines until you stop getting parse errors, like Chunk does)...
This question already has answers here:
What will give me something like ruby readline with a default value?
(6 answers)
Closed 6 years ago.
I am using to Ruby to write a small command line utility to search Pubmed. Right now, I prompt the user for a query and display the results, and the user has the option of appending to the query or entering an entirely new query. I would like to add the ability to edit the current query; i.e. the prompt should come pre-filled with an editable version of the previous query, like so:
Enter query: <PREVIOUS QUERY HERE>
It's easy enough to print out the previous query next to the prompt, but how do I make this output editable, as if the user had typed it herself?
#casper:
Thank you for the response Casper. I tried the code that you supplied below, and it does indeed work on its own. Strangely enough, it doesn't seem to work when I try to use it in a gem. My gem is called db_hippo. I added rb-readline as a dependency in my gemspec, and I put the extension to RbReadline in lib/db_hippo/rb-readline.rb
module DbHippo
module RbReadline
<CASPER'S EXTENSION HERE>
end
end
I wish to use the functionality in another submodule of DbHippo, DbHippo::Source. In DbHippo::Source I added at the top:
require 'rb-readline'
require 'db_hippo/rb-readline'
Then in one of the methods of DbHippo::Source, I have:
RbReadline.prefill_prompt(query)
query = Readline.readline("Query: ", true)
The query variable is definitely not empty, but for some reason in this context the prompt doesn't get prefilled. I also notice that if I put the extension in the same file (lib/db_hippo/rb-readline) without making it a submodule of DbHippo, I get the error: uninitialized constant DbHippo::Source::Readline (NameError) on the line:
query = Readline.readline("Query: ", true)
This all seems to have something to do with proper naming of modules, require statements, and gems. This is the first gem I've tried to build. Any idea what's going wrong here?
Maybe googlers will find this useful.
With plain Readline on Ruby 2.1 you could use:
def ask(prompt, default=nil)
if default
Readline.pre_input_hook = -> {
Readline.insert_text(default)
Readline.redisplay
# prevent re-trigger on every `readline`
Readline.pre_input_hook = nil
}
end
data = Readline.readline("#{prompt}: ")
return data.chomp
end
ask("MOAR...?", "COMPUTARS!") # displays: MOAR...? COMPUTARS!
At the prompt the text COMPUTARS! will be editable
You can do it with RbReadline:
require 'rubygems'
require 'rb-readline'
module RbReadline
def self.prefill_prompt(str)
#rl_prefill = str
#rl_startup_hook = :rl_prefill_hook
end
def self.rl_prefill_hook
rl_insert_text #rl_prefill if #rl_prefill
#rl_startup_hook = nil
end
end
RbReadline.prefill_prompt("Previous query")
str = Readline.readline("Enter query: ", true)
puts "You entered: #{str}"
I tried using 'Tidy' in an HTML document for the first time yesterday, and got...
/tmp/temp_textmate.Z2P0KX:30:in `<main>': undefined method `empty?' for nil:NilClass (NoMethodError)
I've not done anything to the code in the bundle...
#!/usr/bin/env ruby -wKU
require ENV['TM_SUPPORT_PATH'] + '/lib/ui.rb'
require ENV['TM_SUPPORT_PATH'] + '/lib/exit_codes.rb'
result = `"${TM_TIDY:-tidy}" -f /tmp/tm_tidy_errors -iq -utf8 \
-wrap 0 --tab-size $TM_TAB_SIZE --indent-spaces $TM_TAB_SIZE \
--indent yes \
${TM_XHTML:+-asxhtml --output-xhtml yes} \
${TM_SELECTED_TEXT:+--show-body-only yes} \
--enclose-text yes \
--doctype strict \
--wrap-php no \
--tidy-mark no`
status = $?.exitstatus
at_exit { File.unlink('/tmp/tm_tidy_errors') } # Clean up error log
if status == 2 # Errors
msg = "Errors: " + File.read('/tmp/tm_tidy_errors')
TextMate.exit_show_tool_tip msg
elsif status == 1 # Warnings - use output but also display notification with warnings
log = File.read('/tmp/tm_tidy_errors').to_a.select do |line|
! (ENV['TM_SELECTED_TEXT'] and (line.include?('Warning: missing <!DOCTYPE> declaration') or line.include?("Warning: inserting missing 'title' element")))
end.join rescue nil
unless log.empty?
options = {
:title => "Tidy Warnings",
:summary => "Warnings for tidying your document (press escape to close):",
:log => log
}
TextMate::UI.simple_notification(options)
end
end
if ENV['TM_SOFT_TABS'] == "YES"
print result
else
in_pre = false
result.each_line do |line|
unless in_pre
tab_size = ENV["TM_TAB_SIZE"].to_i
space, text = /( *)(.*)/m.match(line)[1..2]
line = "\t" * (space.length / tab_size).floor + " " * (space.length % tab_size) + text
end
print line
in_pre = true if line.include?("<pre>")
in_pre = false if line.include?("</pre>")
end
end
The problem line is unless log.empty?.
I'm running TextMate 1.5.10 (1631) on OS X 10.6.6. I recently installed rvm and upgraded default Ruby to 1.9.2, though forcing TextMate to use 1.8.7 did not fix the problem.
I had the same problem. I have setup my Textmate to use the RVM version of ruby so that I can quickly test scripts.
I solved the problem by unchecking the "TM_RUBY" for the environment variable I had created.
What appears to be happening is the Textmate scripts that wrapper the /usr/bin/tidy command are not executing properly when using a ruby version other than the one that ships with OSX.
I'm curious to see what happens when Lion comes out. Hopefully, Textmate will take another look at these build-in scripts and give them a little "dusting-off".
If you look at the assignment to log, you'll see this:
log = File.read('/tmp/tm_tidy_errors').to_a.select do |line| ... end.join rescue nil
The rescue nil at the end will put a nil into log if the /tmp/tm_tidy_errors file isn't there or it can't be read or what ever. Then the script will call the .empty? method on nil but the nil object has no such method and the script falls over and dies.
You can suppress the problem by changing rescue nil to rescue '' or by changing unless log.empty? to unless log.nil? || log.empty? but that might not be the real problem.
Do you have a TM_TIDY environment variable set? Is there a tidy command in your PATH? Looks like your Tidy install isn't right (or possible not there at all). My OSX has /usr/bin/tidy and apparently that's standard. Try running that big tidy command by hand in a terminal and see what happens.
I had the same problem too, on a machine running OS X 10.9.5 with Ruby upgraded to ruby 2.0.0. Fixed it by taking mu is too short's suggestion to change unless log.empty? to unless long.nil? || log.empty?. That allowed Tidy to run properly, but the top of my HTML selection was still showing me annoying errors:
ruby: warning: -K is specified; it is for 1.8 compatibility and may cause odd behavior
/Applications/TextMate.app/Contents/SharedSupport/Support/lib/ui.rb:129: warning: assigned but unused variable - pid
I shut that up by changing the first line of the script from #!/usr/bin/env ruby -wKU to #!/usr/bin/env ruby -wKU -W0. Obviously the problems are still there under the hood, but for something helpful but not essential, as this functionality is, I think it's plenty good enough.
I would like to know whether I can get source code a method on the fly, and whether I can get which file is this method in.
like
A.new.method(:a).SOURCE_CODE
A.new.method(:a).FILE
Use source_location:
class A
def foo
end
end
file, line = A.instance_method(:foo).source_location
# or
file, line = A.new.method(:foo).source_location
puts "Method foo is defined in #{file}, line #{line}"
# => "Method foo is defined in temp.rb, line 2"
Note that for builtin methods, source_location returns nil. If want to check out the C source code (have fun!), you'll have to look for the right C file (they're more or less organized by class) and find the rb_define_method for the method (towards the end of the file).
In Ruby 1.8 this method does not exist, but you can use this gem.
None of the answers so far show how to display the source code of a method on the fly...
It's actually very easy if you use the awesome 'method_source' gem by John Mair (the maker of Pry):
The method has to be implemented in Ruby (not C), and has to be loaded from a file (not irb).
Here's an example displaying the method source code in the Rails console with method_source:
$ rails console
> require 'method_source'
> I18n::Backend::Simple.instance_method(:lookup).source.display
def lookup(locale, key, scope = [], options = {})
init_translations unless initialized?
keys = I18n.normalize_keys(locale, key, scope, options[:separator])
keys.inject(translations) do |result, _key|
_key = _key.to_sym
return nil unless result.is_a?(Hash) && result.has_key?(_key)
result = result[_key]
result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
result
end
end
=> nil
See also:
https://rubygems.org/gems/method_source
https://github.com/banister/method_source
http://banisterfiend.wordpress.com/
Here is how to print out the source code from ruby:
puts File.read(OBJECT_TO_GET.method(:METHOD_FROM).source_location[0])
Without dependencies
method = SomeConstant.method(:some_method_name)
file_path, line = method.source_location
# puts 10 lines start from the method define
IO.readlines(file_path)[line-1, 10]
If you want use this more conveniently, your can open the Method class:
# ~/.irbrc
class Method
def source(limit=10)
file, line = source_location
if file && line
IO.readlines(file)[line-1,limit]
else
nil
end
end
end
And then just call method.source
With Pry you can use the show-method to view a method source, and you can even see some ruby c source code with pry-doc installed, according pry's doc in codde-browing
Note that we can also view C methods (from Ruby Core) using the
pry-doc plugin; we also show off the alternate syntax for show-method:
pry(main)> show-method Array#select
From: array.c in Ruby Core (C Method):
Number of lines: 15
static VALUE
rb_ary_select(VALUE ary)
{
VALUE result;
long i;
RETURN_ENUMERATOR(ary, 0, 0);
result = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
rb_ary_push(result, rb_ary_elt(ary, i));
}
}
return result;
}
I created the "ri_for" gem for this purpose
>> require 'ri_for'
>> A.ri_for :foo
... outputs the source (and location, if you're on 1.9).
GL.
-r
Internal methods don't have source or source location (e.g. Integer#to_s)
require 'method_source'
User.method(:last).source
User.method(:last).source_location
I had to implement a similar feature (grab the source of a block) as part of Wrong and you can see how (and maybe even reuse the code) in chunk.rb (which relies on Ryan Davis' RubyParser as well as some pretty funny source file glomming code). You'd have to modify it to use Method#source_location and maybe tweak some other things so it does or doesn't include the def.
BTW I think Rubinius has this feature built in. For some reason it's been left out of MRI (the standard Ruby implementation), hence this hack.
Oooh, I like some of the stuff in method_source! Like using eval to tell if an expression is valid (and keep glomming source lines until you stop getting parse errors, like Chunk does)...
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 commandline.
Is there an equivalent to File.exists? for things in $PATH?
(yes I guess I could parse %x[which scriptINeedToRun] but that's not super elegant.
Thanks!
yannick
UPDATE: Here's the solution I retained:
def command?(command)
system("which #{ command} > /dev/null 2>&1")
end
UPDATE 2: A few new answers have come in - at least some of these offer better solutions.
Update 3: The ptools gem has adds a "which" method to the File class.
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.
Use find_executable method from mkmf which is included to stdlib.
require 'mkmf'
find_executable 'ruby'
#=> "/Users/narkoz/.rvm/rubies/ruby-2.0.0-p0/bin/ruby"
find_executable 'which-ruby'
#=> nil
def command?(name)
`which #{name}`
$?.success?
end
Initially taken from hub, which used type -t instead of which though (and which failed for both zsh and bash for me).
Use MakeMakefile#find_executable0 with Logging Disabled
There are a number of good answers already, but here's what I use:
require 'mkmf'
def set_mkmf_log(logfile=File::NULL)
MakeMakefile::Logging.instance_variable_set(:#logfile, logfile)
end
# Return path to cmd as a String, or nil if not found.
def which(cmd)
old_mkmf_log = MakeMakefile::Logging.instance_variable_get(:#logfile)
set_mkmf_log(nil)
path_to_cmd = find_executable0(cmd)
set_mkmf_log(old_mkmf_log)
path_to_cmd
end
This uses the undocumented #find_executable0 method invoked by MakeMakefile#find_executable to return the path without cluttering standard output. The #which method also temporarily redirects the mkmf logfile to /dev/null to prevent cluttering the current working directory with "mkmf.log" or similar.
You can access system environment variables with the ENV hash:
puts ENV['PATH']
It will return the PATH on your system. So if you want to know if program nmap exists, you can do this:
ENV['PATH'].split(':').each {|folder| puts File.exists?(folder+'/nmap')}
This will print true if file was found or false otherwise.
Here's what I'm using. This is platform neutral (File::PATH_SEPARATOR is ":" on Unix and ";" on Windows), only looks for program files that actually are executable by the effective user of the current process, and terminates as soon as the program is found:
##
# Returns +true+ if the +program+ executable is found in the user's path.
def has_program?(program)
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |directory|
File.executable?(File.join(directory, program.to_s))
end
end
I have this:
def command?(name)
[name,
*ENV['PATH'].split(File::PATH_SEPARATOR).map {|p| File.join(p, name)}
].find {|f| File.executable?(f)}
end
works for full paths as well as commands:
irb(main):043:0> command?("/bin/bash")
=> "/bin/bash"
irb(main):044:0> command?("bash")
=> "/bin/bash"
irb(main):006:0> command?("bush")
=> nil
I'd like to add that which takes the flag -s for silent mode, which only sets the success flag, removing the need for redirecting the output.
This is an improved version based on #mislav's answer. This would allow any type of path input and strictly follows how cmd.exe chooses the file to execute in Windows.
# which(cmd) :: string or nil
#
# Multi-platform implementation of "which".
# It may be used with UNIX-based and DOS-based platforms.
#
# The argument can not only be a simple command name but also a command path
# may it be relative or complete.
#
def which(cmd)
raise ArgumentError.new("Argument not a string: #{cmd.inspect}") unless cmd.is_a?(String)
return nil if cmd.empty?
case RbConfig::CONFIG['host_os']
when /cygwin/
exts = nil
when /dos|mswin|^win|mingw|msys/
pathext = ENV['PATHEXT']
exts = pathext ? pathext.split(';').select{ |e| e[0] == '.' } : ['.com', '.exe', '.bat']
else
exts = nil
end
if cmd[File::SEPARATOR] or (File::ALT_SEPARATOR and cmd[File::ALT_SEPARATOR])
if exts
ext = File.extname(cmd)
if not ext.empty? and exts.any?{ |e| e.casecmp(ext).zero? } \
and File.file?(cmd) and File.executable?(cmd)
return File.absolute_path(cmd)
end
exts.each do |ext|
exe = "#{cmd}#{ext}"
return File.absolute_path(exe) if File.file?(exe) and File.executable?(exe)
end
else
return File.absolute_path(cmd) if File.file?(cmd) and File.executable?(cmd)
end
else
paths = ENV['PATH']
paths = paths ? paths.split(File::PATH_SEPARATOR).select{ |e| File.directory?(e) } : []
if exts
ext = File.extname(cmd)
has_valid_ext = (not ext.empty? and exts.any?{ |e| e.casecmp(ext).zero? })
paths.unshift('.').each do |path|
if has_valid_ext
exe = File.join(path, "#{cmd}")
return File.absolute_path(exe) if File.file?(exe) and File.executable?(exe)
end
exts.each do |ext|
exe = File.join(path, "#{cmd}#{ext}")
return File.absolute_path(exe) if File.file?(exe) and File.executable?(exe)
end
end
else
paths.each do |path|
exe = File.join(path, cmd)
return File.absolute_path(exe) if File.file?(exe) and File.executable?(exe)
end
end
end
nil
end
On linux I use:
exists = `which #{command}`.size.>(0)
Unfortunately, which is not a POSIX command and so behaves differently on Mac, BSD, etc (i.e., throws an error if the command is not found). Maybe the ideal solution would be to use
`command -v #{command}`.size.>(0) # fails!: ruby can't access built-in functions
But this fails because ruby seems to not be capable of accessing built-in functions. But command -v would be the POSIX way to do this.
Solution based on rogeriovl, but complete function with execution test rather than existence test.
def command_exists?(command)
ENV['PATH'].split(':').each {|folder| File.executable?(File.join(folder, command))}
end
Will work only for UNIX (Windows does not use colon as a separator)
This is a tweak of rogeriopvl's answer, making it cross platform:
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
for jruby, any of the solutions that depend on mkmf may not work, as it has a C extension.
for jruby, the following is an easy way to check if something is executable on the path:
main » unix_process = java.lang.Runtime.getRuntime().exec("git status")
=> #<Java::JavaLang::UNIXProcess:0x64fa1a79>
main » unix_process.exitValue()
=> 0
main »
if the executable isn't there, it will raise a runtime error, so you may want to do this in a try/catch block in your actual usage.
#####################################################
# 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
Not so much elegant but it works :).def cmdExists?(c)
system(c + " > /dev/null")
return false if $?.exitstatus == 127
true
end
Warning: This is NOT recommended, dangerous advice!