检查,如果一个易于得到安装软件包,然后将其安装,如果它不在Linux上?
题
我工作的一个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>
找到什么样的包拥有的 command
, ,尝试:
dpkg -S `which <command>`
进一步详情,请参阅文章 找出如果包装Linux 和 软件包抄.
其他提示
要一点更加明确,这里有点bash脚本中,用于检查一个包,如果需要安装它。当然,可以在发现该包丢失,例如简单地用一个错误代码退出做其他事情。
PKG_OK=$(dpkg-query -W --showformat='${Status}\n' the.package.name|grep "install ok installed")
echo Checking for somelib: $PKG_OK
if [ "" == "$PKG_OK" ]; then
echo "No somelib. Setting up somelib."
sudo apt-get --force-yes --yes install the.package.name
fi
如果该脚本的GUI内运行(例如,它是一个鹦鹉螺脚本),你可能会想用“gksudo”一个替换“须藤”调用。
此一衬垫返回1(安装)或0(未安装)为 '纳米' 包..
$(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed")
即使在封装中不存在/不可用。
下面的例子将安装“纳米”包,如果它没有被安装..
if [ $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed") -eq 0 ];
then
apt-get install nano;
fi
我提供这种更新,因为Ubuntu加入其"个人包档案"(PPA)只是因为这个问题的回答,并PPA包,有不同的结果。
地Debian库中包装不:
~$ dpkg-query -l apache-perl ~$ echo $? 1
PPA包装上注册的主机和安装:
~$ dpkg-query -l libreoffice ~$ echo $? 0
PPA包装上注册的东道但是没有安装:
~$ 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.
还张贴在: https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt/427898
dpkg -s
方案使用情况
我喜欢 dpkg -s
因为它退出状况 1
如果任何的软件包是没有安装,使它容易实现自动化:
pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
sudo apt-get install $pkgs
fi
man dpkg
没有文件的出口状况不幸的是,但我认为这应该是合理的安全要依靠:
-s, --status package-name...
Report status of specified package.
参见:
测试Ubuntu18.10.
UpAndAdam写道:
但是你不能简单地依靠返回代码这里的脚本
在 我 体验你 可以 依靠dkpg的出口码。
返回代码 这样的话-s 是 0 如果包装和 1 如果不是,所以最简单的解决办法,我发现是:
dpkg -s <pkg-name> 2>/dev/null >/dev/null || sudo apt-get -y install <pkg-name>
工作正常对我来说...
这似乎运作得很好。
$ sudo dpkg-query -l | grep <some_package_name> | wc -l
- 它或者返回
0
如果没有安装或者一些号码> 0
如果安装。
我发现所有的解决方案上述可以产生假阳性如果安装一个包,然后除去尚未安装包保留在系统中。
要复制:
安装包apt-get install curl
结果
除去包apt-get remove curl
现在测试上述的答案。
下面的命令似乎解决此条件:结果
dpkg-query -W -f='${Status}\n' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'
这将导致一个明确的 的安装或的未安装的强>
我在一个基于 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
错误消息容易得多比大多数其他的解析,因为它不包括像“卸载的”状态。它也可以同时检查多个包,有些东西你不能只是错误代码做的。
说明/示例:
$ 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
因为在评论中提到,这可能会意外升级你不打算包;不是真正的预期是稳定自动化过程是个好主意。
$name="rsync"
[ `which $name` ] $$ echo "$name : installed" || sudo apt-get install -y $name
这将做到这一点。 apt-get install
是幂等的。
sudo apt-get install command
使用:
apt-cache policy <package_name>
如果没有安装,它将显示:
Installed: none
,否则它会显示:
Installed: version
此功能已经存在于Ubuntu和Debian,在 command-not-found
强>包。
apt list [packagename]
似乎是做dpkg和年长APT- *工具以外最简单的方法
which <command>
if [ $? == 1 ]; then
<pkg-manager> -y install <command>
fi
我在搬运工运行试验时,而不是在本地的也有类似的要求。基本上,我只是想安装发现,如果他们没有安装任何的.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文件名称是一个较新的版本,那么这将不会覆盖目前安装的软件包。
有关Ubuntu的是,APT提供一个相当体面的方式来做到这一点。下面是谷歌浏览器的示例:
apt -qq list google-chrome-stable 2>/dev/null | grep -qE "(installed|upgradeable)" || apt-get install google-chrome-stable
我重定向错误输出到零,因为容易警告不要使用它的“不稳定(CLI)”。我怀疑名单包是稳定的,所以我认为这是确定以抛出这个警告了。所述-qq使得易于超静
此命令是最令人难忘的:
dpkg --get-selections <package-name>
如果它的安装它打印:
<包名称>安装
否则它打印
没有包找到符合<包名称>
此是在Ubuntu 12.04.1(精确穿山甲)测试
许多事情已被告知但对我来说最简单的方法是:
dpkg -l | grep packagename
在击:
PKG="emacs"
dpkg-query -l $PKG > /dev/null || sudo apt install $PKG
请注意,您可以在PKG几个包的字符串。
我使用下面的方法:
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
看来,时下apt-get
有一个选项--no-upgrade
,只是做了OP想要什么:
--no-upgrade
不升级软件包。当配合使用,安装,没有任何升级将会阻止,如果他们已经安装了升级列出的软件包。
这 https://linux.die.net/man/8/apt联机帮助-get
因此可以使用
apt-get install --no-upgrade package
和仅如果它不是package
将被安装。