我正在使用Ubuntu系统,并且目前正在进行以下操作:
if ! which command > /dev/null; then
echo -e "Command not found! Install? (y/n) \c"
read
if "$REPLY" = "y"; then
sudo apt-get install command
fi
fi
这是大多数人会做的吗?还是有更优雅的解决方案?
在本地运行测试而不是在Docker中运行时,我有一个类似的需求。基本上,如果尚未安装任何.deb文件,我只想安装找到的.deb文件。
# If there are .deb files in the folder, then install them
if [ `ls -1 *.deb 2> /dev/null | wc -l` -gt 0 ]; then
for file in *.deb; do
# Only install if not already installed (non-zero exit code)
dpkg -I ${file} | grep Package: | sed -r 's/ Package:\s+(.*)/\1/g' | xargs dpkg -s
if [ $? != 0 ]; then
dpkg -i ${file}
fi;
done;
else
err "No .deb files found in '$PWD'"
fi
我想唯一的问题就是它没有检查软件包的版本号,所以如果.deb文件是一个更新的版本,那么它就不会覆盖当前安装的软件包。
建议使用类似以下内容的答案:
dpkg-query --showformat '${db:Status-Status}\n' --show $package | grep -q '^installed$'
dpkg-query --showformat '${Status}\n' --show $package | grep -q '^install ok installed$'
都是正确的。
但是如果您安装了dpkg-dev
软件包,并且不仅想检查软件包是否已安装,而且还要:
那么您可以滥用dpkg-checkbuilddeps
工具来完成此任务:
dpkg-checkbuilddeps -d apt /dev/null
这将检查 apt 是否已安装。
以下将检查 apt 是否已安装至少 2.3.15 版本,grep 是否以 amd64 安装,并且虚拟包 x-window-manager
是否由某些已安装的包提供:
dpkg-checkbuilddeps -d 'apt (>= 2.3.15), grep:amd64, x-window-manager' /dev/null
dpkg-checkbuilddeps 的退出状态将告诉脚本依赖项是否已满足。由于此方法支持传递多个软件包,因此即使您想检查是否安装了多个软件包,您也只需要运行一次 dpkg-checkbuilddeps
。
apt list [packagename]
似乎是除了 dpkg 和旧版 apt-* 工具之外最简单的方法。
这个命令是最令人难忘的:
dpkg --get-selections <package-name>
否则,它会打印以下内容:<package-name> 安装
此内容在 Ubuntu 12.04.1(Precise Pangolin)上进行了测试。未找到与 <package-name> 匹配的软件包。
这个代码有点基于你的,只是更加“优雅”一些。因为我很无聊。
#!/bin/bash
FOUND=("\033[38;5;10m")
NOTFOUND=("\033[38;5;9m")
PKG="${@:1}"
command ${PKG} &>/dev/null
if [[ $? != 0 ]]; then
echo -e "${NOTFOUND}[!] ${PKG} not found [!]"
echo -e "${NOTFOUND}[!] Would you like to install ${PKG} now ? [!]"
read -p "[Y/N] >$ " ANSWER
if [[ ${ANSWER} == [yY] || ${ANSWER} == [yY][eE][sS] ]]; then
if grep -q "bian" /etc/os-release; then
sudo apt-get install ${PKG}
elif grep -q "arch" /etc/os-release; then
if [[ -f /bin/yay ]] || [[ -f /bin/yaourt ]]; then
yaourt -S ${PKG} 2>./err || yay -S ${PKG} 2>./err
else
sudo pacman -S ${PKG}
fi
elif grep -q "fedora" /etc/os-release; then
sudo dnf install ${PKG}
else
echo -e "${NOTFOUND}[!] This script couldn't detect your package manager [!]"
echo -e "${NOTFOUND}[!] Manually install it [!]"
fi
elif [[ ${ANSWER} == [nN] || ${ANSWER} == [nN][oO] ]]; then
echo -e "${NOTFOUND}[!] Exiting [!]"
fi
else
echo -e "${FOUND}[+] ${PKG} found [+]"
fi
#!/bin/bash
# Call the command for the package silently
helm > /dev/null
# Get the exit code of the last command
command_exit_code="$(echo $?)"
# Run installation if exit code is not equal to 0
if [ "$command_exit_code" -ne "0" ]; then
# Package does not exist: Do the package installation
else
echo "Skipping 'helm' installation: Package already exists"
fi;
which curl >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "curl is installed."
else
echo "curl is not installed."
fi
我使用这个解决方案,因为我觉得它最直接了当。
function must_install(){
return "$(apt -qq list $var --installed 2> /dev/null |wc -l)"
}
function install_if() {
unset install
for var in "$@"
do
if $(must_install $var)
then
install+="${var} "
fi
done
if [ -n "$install" ];
then
sudo apt-get install -qy $install
fi
}
很好的一点是,must_install
返回 1 或 0,然后从调用的 if
中解释为真或假,所以我们不需要使用 []
进行任何 test
。
install_if
接受由空格分隔的任意数量的软件包。
问题在于 apt
不应该在脚本中使用,因此这可能随时停止工作。 8)
which mySQL 2>&1|tee 1> /dev/null
if [[ "$?" == 0 ]]; then
echo -e "\e[42m MySQL already installed. Moving on...\e[0m"
else
sudo apt-get install -y mysql-server
if [[ "$?" == 0 ]]; then
echo -e "\e[42mMy SQL installed\e[0m"
else
echo -e "\e[42Installation failed\e[0m"
fi
fi
所有的答案都很好,但对于像我这样的初学者来说似乎有些复杂。所以这里是适合我的解决方案。我的Linux环境是CentOS,但不能确认它是否适用于所有发行版。
PACKAGE_NAME=${PACKAGE_NAME:-node}
if ! command -v $PACKAGE_NAME > /dev/null; then
echo "Installing $PACKAGE_NAME ..."
else
echo "$PACKAGE_NAME already installed"
fi
command -v <command>
而不是which <command>
。另请参见如何在Bash脚本中检查程序是否存在。 - jwwapt install
已经安装的软件包也会将其标记为手动安装,如果该软件包以前被设置为自动安装,则会产生非常不希望的副作用。 - MestreLion