Having several scripts which follow the below pattern, and I'm curious if you folks have suggestions on reducing the number of lines or if you're doing this more streamlined?
What I don't like necessarily is that I'm using too many $? checks, and end up with nested if loops - not sure if that is a bad thing though.
Code I'm looking to optimize but still keep the functionality is like this:
wget -V > /dev/null 2>&1
if [ $? -ne 0 ]; then
apt install wget
if [ $? -ne 0 ]; then
"failed to install wget"
fi
fi
oneliner using hash
:
hash wget 2>/dev/null || echo 'wget is not installed'
If you need to install, you can do
hash wget 2>/dev/null || apt install -y wget || echo 'failed to install wget'
again, oneliner.
More specifically, hash
is a reliable way in shell to check if a binary exists in $PATH
. you can check info about hash
as following:
$ help hash
hash: hash [-lr] [-p pathname] [-dt] [name ...]
Remember or display program locations.
Determine and remember the full pathname of each command NAME. If
no arguments are given, information about remembered commands is displayed.
Options: ...
Exit Status:
Returns success unless NAME is not found or an invalid option is given.
In general, you don't need to check $?
explicitly unless you are looking for a particular non-zero exit code. You can rewrite your code as:
if ! wget -V &> /dev/null; then
if ! apt install wget; then
echo "failed to install wget"
fi
fi
Or, even more concisely:
wget -V &> /dev/null || apt install wget || echo "failed to install wget"
I try to get the big picture behind, and I think you try to re-invent the wheel.
The said wheel is command-not-found
on debian and derivatives.
It makes proposition when a command failed automatically.
You just have to do :
apt-get install command-not-found
update-command-not-found
wget -V # or any missing command
If this is an installer script, don't check, just install. Any packages that are already installed will be skipped anyways:
apt install wget jq texlive-latex-base || exit 1
If this is a normal script, don't install missing dependencies , especially not without the user's consent. This is not the script's job, and it's much more intrusive than helpful.
If you still want to do it, just put it in a function. Here's an example:
require() {
# Assume $1 is command and $3 is package (or same as command)
set -- "$1" from "${3:-$1}"
if ! { type "$1" > /dev/null 2>&1 || apt install "$3"; }
then
echo "$1 was missing, but installation of $3 failed" >&2
exit 1
fi
}
require wget
require jq
require latex from texlive-latex-base
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.