Short Answer
On linux:
is_bin_on_path = function(bin) {
exit_code = suppressWarnings(system2("command", args = c("-v", bin), stdout = FALSE))
return(exit_code == 0)
}
Example usage:
is_bin_on_path("ls")
# TRUE
is_bin_on_path("git")
# TRUE
is_bin_on_path("madeup")
# FALSE
Tell me more
This answer recommends avoiding using which
to determine whether an executable is found on the system PATH
. They recommend avoiding which
as it doesn't consistently set exit codes across different operating systems, and as it can apparently do other "evil things".
Instead, OP advocates using command
as a safer alternative to which
.
We can invoke command
from system2()
as:
system2("command", args = c("-v", executable))
where executable
is a string representing the program you are checking for the existence of. eg. "git"
, "python"
, ...
If executable
is on the system PATH
, the location of the executable is printed. If we wish, we can suppress this by calling system2()
with stdout = FALSE
:
system2("command", args = c("-v", executable), stdout = FALSE)
If executable
isn't on the system PATH
, system2()
will raise a warning:
system2("command", args = c("-v", executable), stdout = FALSE)
# Error in paste(c(env, shQuote(command), args), collapse = " ") :
# object 'executable' not found
To suppress this warning we can wrap the command system2()
command in a suppressWarnings()
.
Finally, we should note that by default system()
and system2()
return the exit code of the invoked command, rather than the output of the command itself (as you might expect).
If the desired executable
does exist on the system PATHA
, our invocation of system2("command")
will return with an exit code of 0
. Hence we can convert the exit code to a Boolean representing whether the executable exists on the system PATH
as:
exit_code = suppressWarnings(system2("command", args = c("-v", bin)))
bin_on_path = exit_code == 0
Wrapping this up into something reusable we arrive at the function:
is_bin_on_path = function(bin) {
exit_code = suppressWarnings(system2("command", args = c("-v", bin), stdout = FALSE))
return(exit_code == 0)
}
Other notes
The more modern replacement of system2()
, processx()
, at least in my experience, seems unhappy calling command
. I'm not sure why this is the case.