This script simply installs the chosen packages if they're not present on a Linux system using the apt
package manager. Notes on improvements of any aspect are welcome!
setup_env.sh
#!/usr/bin/env bash
set -euo pipefail
install_if_not_exist() {
if dpkg -s "1ドル" &>/dev/null; then
PKG_EXIST=$(dpkg -s "1ドル" | grep "install ok installed")
if [ -z "$PKG_EXIST" ]; then
sudo apt install "1ドル" -y
fi
else
sudo apt install "1ドル" -y
fi
}
sudo apt update -y
install_if_not_exist aria2
install_if_not_exist coreutils
install_if_not_exist gawk
install_if_not_exist jq
install_if_not_exist moreutils
install_if_not_exist sed
2 Answers 2
Good
- Yay for using a function to contain most of the functionality
- Good indentation
- It looks like you're following shellcheck
- Good names for the variable and function
Suggestions
- Use double square brackets for conditionals. They will lead to fewer surprises.
- Instead of repeating the
sudo apt install "1ドル" -y
I'd change theif [ -z "$PKG_EXIST" ]
... toif [[ -n "$PKG_EXIST" ]]; then; return; fi
and move thesudo apt install "1ドル" -y
line to the bottom of the function definition. Coded more fully below. - I like to comment the strict mode line(s) since many folks don't realize what this is doing.
- Check to make sure the function only gets one argument. You might later accidentally put a space into a package name and this would catch that.
rewrite of central function
install_if_not_exist() {
if dpkg -s "1ドル" &>/dev/null; then
PKG_EXIST=$(dpkg -s "1ドル" | grep "install ok installed")
if [[ -n "$PKG_EXIST" ]]; then
return
fi
fi
sudo apt install "1ドル" -y
}
-
\$\begingroup\$ How would your second suggestion look in code? There are a couple ways I'm interpreting it. \$\endgroup\$T145– T1452021年06月11日 18:25:57 +00:00Commented Jun 11, 2021 at 18:25
-
\$\begingroup\$ I added the code I'm suggesting to the answer. \$\endgroup\$chicks– chicks2021年06月11日 18:55:02 +00:00Commented Jun 11, 2021 at 18:55
-
\$\begingroup\$ Thanks! I figured it was something like this, but got stressed out not seeing the first condition there. \$\endgroup\$T145– T1452021年06月11日 20:40:44 +00:00Commented Jun 11, 2021 at 20:40
Using sudo
in scripts is an anti-pattern. It can irritate the user with repeated password requests (depending on how sudo
is configured).
For this script, it's better to assume (or test) that the user is already sufficiently privileged. And explicitly set PATH
at the beginning to avoid trojan horses taking advantage of the escalated privilege:
PATH=/usr/sbin:/usr/bin
The only thing in this script that's not standard POSIX shell is set -o pipefail
, so it could easily be made portable and more efficient.
-
1\$\begingroup\$ What happens if the script already has privileges set? Wouldn't that naturally restrict access? If I apply that PATH statement at the head of my script, does that mean
sudo
can be removed? What could make it more portable and efficient? \$\endgroup\$T145– T1452021年06月11日 20:38:56 +00:00Commented Jun 11, 2021 at 20:38 -
\$\begingroup\$ Not sure what you mean when you ask "Wouldn't that naturally restrict access?" I'm suggesting that instead of
sudo
within the script, then it's better for users to run the script itself using sudo (or other means). In which casesudo
in the script isn't necessary. And for scripts run as a superuser, it's wise to setPATH
to a known value. \$\endgroup\$Toby Speight– Toby Speight2021年06月12日 09:55:50 +00:00Commented Jun 12, 2021 at 9:55
install_if_notexist foo
every time you want to install a new package. \$\endgroup\$apt install
, and it would tell you which of the requested packages are already installed (and therefore it won't install them again)? \$\endgroup\$apt
is more efficient when you install all the packages you want in one transaction. \$\endgroup\$