我有新用户运行的脚本来配置他们的系统,基本上是一个bash脚本,它有一个很大的for循环,如下所示:
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之间插入。apt-get update的apt-get update任务。发布于 2014-08-04 21:58:33
我来到这里的问题同样是想要检测apt-get和dpkg使用的锁文件是否被锁定,而忽略了这是否是要执行的最相关的测试(在我的例子中是如此)。最后,我使用了以下Python代码片段:
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发布于 2014-05-12 16:46:18
正确的解决方案是用一个虚拟包替换复杂的脚本,这个包是您想要安装的所有其他包中的Depends:。
equivs包是构建这样一个虚拟包的简单方法(虽然一开始不是很直观)。
顺便说一句,这不是一次临时攻击;例如,Debian build-essential包就是这样进入整个构建链的。
发布于 2014-05-14 18:56:25
@tripleee的答案是最好的,但如果出于某种原因,您不能这样做(我知道,在一些罕见的情况下,这是真的--因为这是对我们的),正确的做法是发出一个命令,而不是使用循环:
apt-get -qq install -y --force-yes $DEBShttps://stackoverflow.com/questions/23610628
复制相似问题