我正在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
大多数人都会这么做吗?还是有更优雅的解决方案?
我正在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
大多数人都会这么做吗?还是有更优雅的解决方案?
当前回答
要检查是否安装了packagename,输入:
dpkg -s <packagename>
您还可以使用dpkg-query,它的输出更简洁,而且还接受通配符。
dpkg-query -l <packagename>
要找到哪个包拥有该命令,请尝试:
dpkg -S `which <command>`
有关更多详细信息,请参见文章“了解Linux中是否安装了软件包”和dpkg备忘单。
其他回答
在本地而不是Docker中运行测试时,我也有类似的需求。基本上,我只想安装任何尚未安装的.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文件是一个更新的版本。这样就不会覆盖当前安装的包。
我使用这个解决方案,因为我发现它是最直接的。
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将其解释为true或false,因此我们不需要使用[]进行任何测试。
Install_if接受按空格分隔的任意数量的包。
问题是apt并不打算在脚本中使用,因此这可能在任何时候停止工作。8)
我根据Nultyi的回答选择了一个:
MISSING=$(dpkg --get-selections $PACKAGES 2>&1 | grep -v 'install$' | awk '{ print $6 }')
# Optional check here to skip bothering with apt-get if $MISSING is empty
sudo apt-get install $MISSING
基本上,来自dpkg——get-selections的错误消息比其他大多数错误消息更容易解析,因为它不包括“deinstall”这样的状态。它还可以同时检查多个包,这是仅使用错误代码无法做到的。
解释/例子:
$ dpkg --get-selections python3-venv python3-dev screen build-essential jq
dpkg: no packages found matching python3-venv
dpkg: no packages found matching python3-dev
screen install
build-essential install
dpkg: no packages found matching jq
因此grep从列表中删除已安装的包,awk从错误消息中提取包名,导致MISSING='python3-venv python3-dev jq',它可以简单地插入到安装命令中。
我不是盲目地发布apt-get install $PACKAGES,因为正如评论中提到的,这可能会意外地升级你没有计划的包;对于期望稳定的自动化流程来说,这并不是一个好主意。
这个特性已经存在于Ubuntu和Debian的command-not-found包中。
Ubuntu添加了它的“个人包存档”(PPA),而PPA包有不同的结果。
A native Debian repository package is not installed: ~$ dpkg-query -l apache-perl ~$ echo $? 1 A PPA package registered on the host and installed: ~$ dpkg-query -l libreoffice ~$ echo $? 0 A PPA package registered on the host, but not installed: ~$ dpkg-query -l domy-ce ~$ echo $? 0 ~$ sudo apt-get remove domy-ce [sudo] password for user: Reading package lists... Done Building dependency tree Reading state information... Done Package domy-ce is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
测试APT中是否安装了软件包