How would I validate that a program exists? Which would then either return an error and exit or continue with the script.
It seems like it should be easy, but it's been stumping me.
How would I validate that a program exists? Which would then either return an error and exit or continue with the script.
It seems like it should be easy, but it's been stumping me.
The which
command might be useful. man which
It returns 0 if the executable is found, 1 if it's not found or not executable:
NAME
which - locate a command
SYNOPSIS
which [-a] filename ...
DESCRIPTION
which returns the pathnames of the files which would be executed in the
current environment, had its arguments been given as commands in a
strictly POSIX-conformant shell. It does this by searching the PATH
for executable files matching the names of the arguments.
OPTIONS
-a print all matching pathnames of each argument
EXIT STATUS
0 if all specified commands are found and executable
1 if one or more specified commands is nonexistent or not exe-
cutable
2 if an invalid option is specified
Nice thing about which is that it figures out if the executable is available in the environment that which is run in - saves a few problems...
Try using:
test -x filename
or
[ -x filename ]
From the bash manpage under "Conditional Expressions":
-x file True if file exists and is executable.
It depends whether you want to know whether it exists in one of the directories in the $PATH
variable or whether you know the absolute location of it. If you want to know if it is in the $PATH
variable, use
if which programname >/dev/null; then
echo exists
else
echo does not exist
fi
otherwise use
if [ -x /path/to/programname ]; then
echo exists
else
echo does not exist
fi
The redirection to /dev/null/
in the first example suppresses the output of the which
program.
Yes; avoid "which". Not only is it an external process you're launching for doing very little (meaning builtins like "type" are way cheaper), you can also rely on the builtins to actually do what you want.
Why care?
Don't use which. Instead use type.
$ type -P foo &>/dev/null || { echo "I require foo but it's not installed. Aborting." >&2; exit 1; }
For those interested, none of the methodologies above work if you wish to detect an installed library. I imagine you are left either with physically checking the path (potentially for header files and such), or something like this (if you are on a Debian-based distro):
dpkg --status libdb-dev | grep -q not-installed
if [ $? -eq 0 ]; then
apt-get install libdb-dev
fi
As you can see from the above, a "0" answer from the query means the package is not installed. This is a function of "grep" - a "0" means a match was found, a "1" means no match was found.
I had no success with this solution, I had to modify it a little:
dpkg --get-selections | grep -q linux-headers-$(uname -r)
if [ $? -eq 1 ]; then
apt-get install linux-headers-$(uname -r)
fi
I have a function defined in my .bashrc that makes this easier.
command_exists () {
type "$1" &> /dev/null ;
}
Here's an example of how it's used (from my .bash_profile
.)
if command_exists mvim ; then
export VISUAL="mvim --nofork"
fi