首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检测/避免多个apt/dpkg安装

检测/避免多个apt/dpkg安装
EN

Stack Overflow用户
提问于 2014-05-12 13:39:42
回答 3查看 2K关注 0票数 2

我有新用户运行的脚本来配置他们的系统,基本上是一个bash脚本,它有一个很大的for循环,如下所示:

代码语言:javascript
复制
DEBCOUNT=${#DEBS[@]}
for (( i=0; i<${DEBCOUNT}; i++ ));
do
  PACKAGE=${DEBS[$i]}
  dpkg -s ${PACKAGE} >> /dev/null
  if [ ${PIPESTATUS[0]} -ne 0 ]; then
    echo -n  =========== Installing ${PACKAGE}
    echo "  ( $((${i}*100/${DEBCOUNT}))% )"

    apt-get -qq install -y --force-yes  ${PACKAGE}
    if [ $? -ne 0 ]; then
      echo ERROR: Failed to install required package ${PACKAGE}
      exit 1
    fi
  else
    echo -n  =========== Skipping ${PACKAGE}
    echo "  ( $((${i}*100/${DEBCOUNT}))% )"
  fi
done

大型DEBS数组是要安装在新系统(主要是编译器和编辑器)上的50个ish软件包的列表。

它工作得很好,除了某些系统进程在后台启动并开始更新APT数据库的情况外。然后它在dpkg: error: dpkg status database is locked by another process上失败了。

是否有一种优雅/健壮的方法来避免此错误?要么通过检测它,然后以某种方式等待直到它是免费的,或者通过阻止它在最初的位置。

反应

  • 我不想就这么把锁文件拿掉。试着安装我的东西和系统同时做的任何事情都会不可避免地破坏一些东西。
  • 我无法在开始时进行一次检查,因为我所看到的似乎表明,另一个过程是进行我想要的等待,并在我的两个apt-get之间插入。
  • 这不是一个进程做锁..有时我认为这是ubuntu软件更新程序,有时我认为这是一个运行大型apt-get updateapt-get update任务。
EN

回答 3

Stack Overflow用户

发布于 2014-08-04 21:58:33

我来到这里的问题同样是想要检测apt-getdpkg使用的锁文件是否被锁定,而忽略了这是否是要执行的最相关的测试(在我的例子中是如此)。最后,我使用了以下Python代码片段:

代码语言:javascript
复制
import fcntl

def is_dpkg_active():
    """
    Check whether ``apt-get`` or ``dpkg`` is currently active.

    This works by checking whether the lock file ``/var/lib/dpkg/lock`` is
    locked by an ``apt-get`` or ``dpkg`` process, which in turn is done by
    momentarily trying to acquire the lock. This means that the current process
    needs to have sufficient privileges.

    :returns: ``True`` when the lock is already taken (``apt-get`` or ``dpkg``
              is running), ``False`` otherwise.
    :raises: :py:exc:`exceptions.IOError` if the required privileges are not
             available.

    .. note:: ``apt-get`` doesn't acquire this lock until it needs it, for
              example an ``apt-get update`` run consists of two phases (first
              fetching updated package lists and then updating the local
              package index) and only the second phase claims the lock (because
              the second phase writes the local package index which is also
              read from and written to by ``dpkg``).
    """
    with open('/var/lib/dpkg/lock', 'w') as handle:
        try:
            fcntl.lockf(handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
            return False
        except OSError:
            return True
票数 4
EN

Stack Overflow用户

发布于 2014-05-12 16:46:18

正确的解决方案是用一个虚拟包替换复杂的脚本,这个包是您想要安装的所有其他包中的Depends:

equivs包是构建这样一个虚拟包的简单方法(虽然一开始不是很直观)。

顺便说一句,这不是一次临时攻击;例如,Debian build-essential包就是这样进入整个构建链的。

票数 1
EN

Stack Overflow用户

发布于 2014-05-14 18:56:25

@tripleee的答案是最好的,但如果出于某种原因,您不能这样做(我知道,在一些罕见的情况下,这是真的--因为这是对我们的),正确的做法是发出一个命令,而不是使用循环:

代码语言:javascript
复制
apt-get -qq install -y --force-yes $DEBS
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23610628

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档