0

I'm using Ruby on Linux. I'd like to test for the existence of a command on the Linux system.

I'd like to not get back the output of the command that I'm testing for.

I'd also like to not get back any output that results from the shell being unable to find the command.

I want to avoid using shell redirection from within the command that I send to the shell. So something like system("foo > /dev/null") would be unsuitable.

I'm ok with using redirection if there is a way to do it from Ruby.

bob
  • 753
  • 4
  • 15
  • 27
  • What do you mean by "is available"? 1. Is installed somewhere on the machine or 2. Is in the $PATH ? If 2. => which $PATH / env / shell / user? You see, it's not that easy to think about that question without shells. If you just need to know if some command is executable, do sth like `system("which foobar")` – Marian Theisen Jan 06 '22 at 06:36
  • Either. I just want to know if the command is available to be called from Ruby. Whether it's installed but not in the path doesn't matter. Unfortunately I can't use something like system("which foobar") because it returns the output of "which foobar". I don't want the return value of the command. I want to *not* have the output of the command. – bob Jan 06 '22 at 07:21
  • Related: https://stackoverflow.com/questions/592620/how-can-i-check-if-a-program-exists-from-a-bash-script – Christopher Oezbek Jan 06 '22 at 10:41

2 Answers2

1

The simplest thing would be just to use system. Let's say you're looking for ls.

irb(main):005:0> system("which ls")
/bin/ls
=> true

If that's off the table, you could peek into the directories in ENV["PATH"] for the executable you're looking for. ENV["PATH"].split(":") would give you an array of directory names to check for the desired command. If you find a file with the right name, you may want to ensure it's an executable.

Chris
  • 26,361
  • 5
  • 21
  • 42
  • The problem with using system("which ls") is that it returns the shells response to "which ls", as illustrated in your example. I don't want that response. If I understand your suggestion of using ENV, I think that could work. But doesn't it seem a little unwieldy? Essentially I'd be doing a kind of grep against the returned filename of every executable in the path. – bob Jan 06 '22 at 07:26
0

I want to avoid using shell redirection from within the command that I send to the shell. So something like system("foo > /dev/null") would be unsuitable. I'm ok with using redirection if there is a way to do it from Ruby.

system("exec which cmd", out: "/dev/null")
puts "Command is available." if ($?).success?

The exec is to explicitly avoid unnecessary forking in the shell.

As a sidenote type -P can be used instead of which, but it relies on Bash and may have surprising effects if script is ported to an environment with a different default shell.

konsolebox
  • 72,135
  • 12
  • 99
  • 105