When writing shell scripts, is the an idiom or swift way to run a program only if it is installed, and if it is not, just let it be (or handle the error in some other way apart from installing it)?
More specifically, I have a lot of servers which I access over ssh
, and whenever I get a new server, I simply copy all my rc-files to it. The .zshrc starts tmux
unless it is already running. Some of the servers (not all) do not have tmux
installed. I do not want to install it because of disk space limitations, I do not want to have different rc-files for different servers, and I do not want my rc-files to be interrupted when executing them.
I have seen solutions involving apt-cache policy <package-name>
, so I guess I could use that and pipe it to something like grep -e 'Installed: (none)'
, but that would assume that the server is running Debian or Ubuntu, which I can not do, and it would only work for packages that were installed with apt
, not things I have installed in other ways.
command -v <command>
is the common (and POSIX) way to check if a command could be executed (is executable and on the $PATH
).
E.g:
command -v tmux >/dev/null &&
tmux a -t name
(>/dev/null
since, if the command exists, its path will be printed to STDOUT.)
It could be nice to put it in a reusable function:
maybe() {
! command -v "${1}" >/dev/null ||
"$@"
}
Then one could use:
maybe tmux a -t name
And if tmux
is available then tmux a -t name
will be run, otherwise it’ll be silently ignored.
Or, if you want some feedback when a command is not available:
maybe() {
if command -v "${1}" >/dev/null
then
"$@"
else
printf 'Command "%s" not available, skipping\n' "${1}" >&2
fi
}