-1

I would like to do something like this:

  1. Ask user which packages to remove interactively
  2. Remove the requested packages

And I want to keep the package system intact while getting the user input.

It is different thing to wait while some other program is changing something in the package management system than to prevent some other program from starting to mess with the package management system while my program is deciding what to do with the package management system and while doing the decided actions.

See a related bug report and comments there.

Currently there are at least two lock files used for locking the dpkg system: '/var/lib/dpkg/lock' and '/var/lib/dpkg/lock-frontend'. I try to lock using the former file by starting the following script as superuser:

#!/bin/bash
exec {var}>/var/lib/dpkg/lock
flock -n $var || { echo was locked already; exit 1; }
read -p 'Now the lock should be active. Press enter to release.'
exit

But I can still use e.g. sudo apt install, so apt does not think the file is locked.

jarno
  • 5,600
  • Are you saying that you want to block access to apt and force folks to use only your script? – user535733 Dec 19 '19 at 21:00
  • @user535733 no, I just want to lock the access while the the script is running like what Synaptic package manager does when it is run by /usr/bin/synaptic-pkexec or by GUI menu. – jarno Dec 19 '19 at 21:19
  • 1
    Why bother? Apt has a lock already. Simply detect apt's lockfile. Or queue actions using aptdaemon and avoid the need to lock. – user535733 Dec 19 '19 at 21:21
  • @user535733 I do not know how to use Apt's lockfile or aptdaemon to get what I want. – jarno Dec 19 '19 at 21:36
  • 5
  • @WinEunuuchs2Unix no – jarno Dec 20 '19 at 13:36
  • Welcome to AskUbuntu! Were you unable to accomplish your desired results using the answers in the called duplicate? Plwase [edit] into your question what you tried, what you expacted to happen and what happened instead. Thank you for helping us help you! – Elder Geek Dec 20 '19 at 14:36
  • @ElderGeek I think I just explained why this is not a duplicate. I feel this is not welcoming, besides I am not new here. If you do not understand the difference, please do not offer any duplicates, and let someone who understand, answer the question. – jarno Dec 20 '19 at 14:57
  • 1
    @jarno, you have my apologies if you feel I was unwelcoming. If you aren't new here, you should be aware of https://askubuntu.com/help/how-to-ask. I'm referring to the "Keep an open mind" part. I understand that you think it's not the same and I follow what you are saying in your question, but for all intents and purposes you are asking how to make some other program wait until your program is done. Same question, different point of view, hence my comment here Cheers! – Elder Geek Dec 22 '19 at 04:31

2 Answers2

2

flock(1) manages flock(2) locks, whereas dpkg and apt use fcntl(2) locks. The two types of locks are completely independent on Linux.

I'm not aware of any shell tool to do the right lock type.

To do what you want to do, write a Python script using python3-apt. This allows you to maintain a frontend lock throughout the operation, ensuring that stuff works correctly.

There is no way to do this correctly from shell, as we do not yet allow callers of apt(1) and friends to hold the frontend lock. It probably makes sense to allow that as well.

  • 1
    python3-apt may not be well known to everyone so a little description about it will help them. Note: "them" includes me in this case. – WinEunuuchs2Unix Dec 29 '19 at 00:37
  • Yes, it would be great, if you could control those locks from shell, and still call apt/dpkg. That may be a use case of for them. – jarno Jan 07 '20 at 07:47
1

One thing you could try is building an interceptor. Move the apt binary to another location (use which apt to find out where it is). Rename it to something like apt-old, then as root create a shell script in the location you originally had apt in, make it executable, and make it look something like this:

apt-old $@

What this will do is automatically pass any arguments you give your interceptor script on to the original apt binary, meaning that you can put anything you like before that line and it will execute it on every run, for example you can add your own file lock check:

#!/usr/bin/bash
if [ -f "/var/file_lock" ]; then
  echo "A program has superior rights to apt at this time."
  exit 1
else
  apt-old $@
fi

This would allow you to make programs calling apt to use a different file check, for one created by your program. This gives you the freedom to create it where and when you like, and still have the benefit of using apt's own file locking mechanisms.

Note that this will not disable the original apt binary, you're only moving it so that your script takes its place in the path.

Minty
  • 1,208
  • Moving a system binary seems extremely... brute-ish. – vidarlo Dec 26 '19 at 13:08
  • Another option is to place the interceptors in /usr/local/bin as that is searched before /usr/bin in PATH. Then you do not have to move the originals, supposed they are not called by their path. – jarno Dec 26 '19 at 13:52
  • That might not work with Synaptic or Unattended Upgrades, though, unless you make interceptors for them, too. – jarno Dec 26 '19 at 15:31
  • This approach also has the problem that apt does not have to lock database always, for example to run apt list --upgradable. – jarno Dec 28 '19 at 21:35