Created
May 12, 2016 14:36
-
-
Save antonioaguilar/fb3bda1ec75cc62e7845c96007b6faa9 to your computer and use it in GitHub Desktop.
Check if a program exists in bash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script | |
Yes; avoid which. Not only is it an external process you're launching for doing very little (meaning builtins like hash, type or command are way cheaper), you can also rely on the builtins to actually do what you want, while the effects of external commands can easily vary from system to system. | |
Why care? | |
Many operating systems have a which that doesn't even set an exit status, meaning the if which foo won't even work there and will always report that foo exists, even if it doesn't (note that some POSIX shells appear to do this for hash too). | |
Many operating systems make which do custom and evil stuff like change the output or even hook into the package manager. | |
So, don't use which. Instead use one of these: | |
$ command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; } | |
$ type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; } | |
$ hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; } | |
If your hash bang is /bin/sh then you should care about what POSIX says. type and hash's exit codes aren't terribly well defined by POSIX, and hash is seen to exit successfully when the command doesn't exist (haven't seen this with type yet). command's exit status is well defined by POSIX, so that one is probably the safest to use. | |
If your script uses bash though, POSIX' rules don't really matter anymore and both type and hash become perfectly safe to use. type now has a -P to search just the PATH and hash has the side-effect that the command's location will be hashed (for faster lookup next time you use it), which is usually a good thing since you probably check for its existence in order to actually use it. | |
As a simple example, here's a function that runs gdate if it exists, otherwise date: | |
gnudate() { | |
if hash gdate 2>/dev/null; then | |
gdate "$@" | |
else | |
date "$@" | |
fi | |
} | |
In summary: | |
Where bash is your shell/hashbang, consistently use hash (for commands) or type (to consider built-ins & keywords). | |
When writing a POSIX script, use command -v. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment