我正在编写脚本来执行一些apt命令,但是我遇到了apt / dpkg数据库被locking的潜在问题,所以我的脚本保存了。 我想在执行任何操作之前检查locking文件(即/ var / lib / dpkg / lock),就像apt在运行命令时一样,但我无法弄清楚执行locking的方式。
锁文件总是在那里,apt-get没有在文件上做一个群。 还有其他什么方法可以检查它是否在使用中? 从strace我看到,apt-get打开文件,但就是这样。 在我的脚本中,我可以打开文件,而apt-get也打开它。
那么我认为这里会有一个简单的答案,但我什么都找不到。 首先,你是否100%确定锁文件总是存在? 尝试运行
lsof /var/lib/dpkg/lock
作为根,看看是否有进程打开。
从我读过的,apt-get做了一个fcntl锁,但是我没有看过要validation的代码。 我猜wuld解释了为什么文件一直在那里,只是根据需要locking它。
那么在你的脚本运行的时候检查一下进程列表,如果apt同时运行,退出呢? 这对你的使用是否足够?
看起来这个人跟你走的路一样,没有太多成功。
我发现apt正在使用fcntl。 由于我使用Ruby作为脚本语言,因此我必须创build自己的函数来查找locking。 原因是因为Ruby没有完全实现fcntl函数。 它只提供函数调用和常量。 build立鸡群结构的能力以及如何通过它们被遗漏或不logging。
这是我发现的那个列表 。
这是我写的function:
def flocked? &block flockstruct = [Fcntl::F_RDLCK, 0, 0, 0, 0].pack("ssqqi") fcntl Fcntl::F_GETLK, flockstruct status = flockstruct.unpack("ssqqi")[0] case status when Fcntl::F_UNLCK return false when Fcntl::F_WRLCK|Fcntl::F_RDLCK return true else raise SystemCallError, status end end
我来到这里寻找类似于gondoi最终使用的解决scheme,但是用Python而不是Ruby编写。 以下似乎运作良好:
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 IOError: return True
从一个shell脚本(参见flock(1) ):
flock --timeout 60 --exclusive --close /var/lib/dpkg/lock apt-get -y -o Dpkg::Options::="--force-confold" upgrade if [ $? -ne 0 ]; then echo "Another process has f-locked /var/lib/dpkg/lock" 1>&2 exit 1 fi