dpkg (and in turn apt) doesn't use flock(2) for locking. Checking the system calls, involved, it seems they use 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
And from this SO post:
In Linux, lockf() is just a wrapper around fcntl(), while flock()
locks are separate (and will only work on local filesystems, not on
e.g. NFS mounts). That is, one process can have an advisory exclusive
flock() lock on a file, while another process has an advisory
exclusive fcntl() lock on that same file. Both are advisory locks,
but they do not interact.
So flock isn't effective in locking it against other package management commands. (Thinking about it... if it were, then the subsequent apt-get would have failed anyway.)
The simplest way I can think of is to create an immutable /var/lib/dpkg/lock file for the duration of the task.
touch /var/lib/dpkg/lock
chattr +i /var/lib/dpkg/lock
Or you can write a short C program (or any language that provides an easy interface to fcntl) that uses fcntl to lock it the way dpkg does.
fcntlorlockfin terminal. – jarno Nov 20 '17 at 14:14/var/lib/dpkg/lockfile for the duration of the task. Or you can write a short C program that usesfcntlto lock it the way dpkg does. – muru Nov 22 '17 at 11:39touch /var/lib/dpkg/lock; chattr +i /var/lib/dpkg/lock– muru Nov 25 '17 at 06:44sudo perl -MFile::FcntlLock -e 'my $fs = new File::FcntlLock; $fs->l_type( F_WRLCK ); $fs->l_whence( SEEK_SET ); $fs->l_start( 0 ); $fs->l_len( 0 ); open my $fh, "+<", "/var/lib/dpkg/lock" or die $!; $fs->lock( $fh, F_SETLK ) or die $fs->error; warn "got lock\n"; system("run some commands")'(requires package libfile-fcntllock-perl). – Slaven Rezic Dec 20 '17 at 16:46chattr +i /var/lib/apt/lists/lock) – Marcus Dec 06 '18 at 08:31