Запущение скрипта
#!/bin/bash
(
flock 9
# ... commands executed under lock ...
fuser -v /var/lib/dpkg/lock
apt-get -f --assume-no install
) 9>/var/lib/dpkg/lock
поскольку суперпользователь не отображает сообщение об ошибке. Но если существует, например. synaptic
выполнение,apt-get
отобразит сообщение об ошибке: "E: не Мог получить блокировку/var/lib/dpkg/lock - открытый (11: Снабдите временно недоступный)".
dpkg
(и в свою очередь склонный), не использует flock(2)
для блокировки. Проверяя системные вызовы, включенные, кажется, что они используют fcntl(2)
:
$ sudo strace -f -e trace=desc apt install foo |& grep -B2 F_SETLK
close(4) = 0
open("/var/lib/dpkg/lock", O_RDWR|O_CREAT|O_NOFOLLOW, 0640) = 4
fcntl(4, F_SETFD, FD_CLOEXEC) = 0
fcntl(4, F_SETLK, {l_type=F_WRLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = -1 EAGAIN (Resource temporarily unavailable)
close(4) = 0
И от этого ТАК отправьте:
В Linux,
lockf()
просто обертка вокругfcntl()
, в то время какflock()
блокировки являются отдельными (и будет только работать над локальными файловыми системами, не над, например, NFS монтируется). Таким образом, один процесс может иметь эксклюзивную консультациюflock()
соедините файл, в то время как другой процесс имеет эксклюзивную консультациюfcntl()
соедините тот же самый файл. Оба - консультативные блокировки, но они не взаимодействуют.
Так flock
не является эффективным при блокировке его против других команд управления пакетом. (Думающий об этом..., если это было, затем последующее apt-get
перестал бы работать так или иначе.)
Самым простым путем я могу думать, должен создать неизменное /var/lib/dpkg/lock
файл на время задачи.
touch /var/lib/dpkg/lock
chattr +i /var/lib/dpkg/lock
Или можно записать короткую программу C (или любой язык, который предоставляет легкий интерфейс fcntl
) это использует fcntl
для блокировки его, путь dpkg делает.