[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Run script after package install, update



On Sun 15 Jun 2025 at 11:33:09 (-0400), Greg Wooledge wrote:
> On Sun, Jun 15, 2025 at 11:07:41 -0400, Boyan Penkov wrote:
> > So ultimately, my problem is addressed; however, the larger question
> > is still open: is there in fact a straightforward way for a user, not
> > the package maintainer, to tell the package management system: "If and
> > only if your operation touched package x, also do this one thing
> > locally."?  I can think of about a million use cases for this: "if you
> > touched maildir-utils, run mu  index." "if you touched offlineimap,
> > run offlineimap" "if you touched etckeeper, re-commit the /etc files"
> > and so on ...
> 
> Since the apt documentation is such complete rubbish, the only ways
> to actually figure out how anything *works* are source diving and
> experimenting.  I do not feel like trying to source-dive through apt
> and its libraries, so I tried an experiment.
> 
> According to the apt.conf(5) man page:
> 
>        Pre-Invoke, Post-Invoke
>            This is a list of shell commands to run before/after invoking
>            dpkg(1). Like options this must be specified in list notation. The
>            commands are invoked in order using /bin/sh; should any fail APT
>            will abort.
> 
> That's clear as mud.  What is "list notation"?  Again, I had to experiment.
> I tried looking for examples, learned that the
> /usr/share/doc/apt/examples/configure-index.gz file documented at the end
> of the man page does not exist, discovered that the file
> /usr/share/doc/apt/examples/configure-index exists instead, read that, and
> found nothing helpful in deciphering what an apt.conf.d/* file should
> look like.
> 
> I looked at other files in /etc/apt/apt.conf.d/ for inspiration, and
> tried searching for the word "list" in the man page, but ultimately it
> came down to experimenting until I got it right.
> 
> Here's what I did:
> 
> 1) I created the file /etc/apt/apt.conf.d/99localexperiment with the
> following contents:
> 
> ====================================================================
> DPkg::Post-Invoke { /usr/local/sbin/dpkg-experiment; };
> ====================================================================
> 
> 2) I created the script /usr/local/sbin/dpkg-experiment with the following
> contents:
> 
> ====================================================================
> #!/bin/sh
> exec > /var/tmp/dpkg-experiment
> printf '%s args' "$#"
> if test "$#" != 0; then
>     printf :
>     printf ' <%s>' "$@"
> fi
> echo; echo
> ps -fp "$$,$PPID"
> echo
> env
> ====================================================================
> 
> and gave it 755 permissions.
> 
> 3) I installed a package by running "sudo apt-get install sl".
> 
> Here's the /var/tmp/dpkg-experiment file that was created as a result:
> 
> ====================================================================
> 0 args
> 
> UID          PID    PPID  C STIME TTY          TIME CMD
> root      487061  487060  0 11:19 pts/27   00:00:00 sh -c /usr/local/sbin/dpkg-experiment
> root      487062  487061  0 11:19 pts/27   00:00:00 /bin/sh /usr/local/sbin/dpkg-experiment
> 
> SUDO_GID=1000
> DPKG_FRONTEND_LOCKED=true
> MAIL=/var/mail/root
> LC_TIME=C
> USER=root
> HOME=/root
> COLORTERM=rxvt-xpm
> SUDO_UID=1000
> LOGNAME=root
> TERM=rxvt-unicode-256color
> PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
> DISPLAY=:0
> LANG=en_US.utf8
> XAUTHORITY=/home/greg/.Xauthority
> LS_COLORS=ln=31:ex=35:cd=44;37:bd=44;37:pi=32
> SUDO_COMMAND=/usr/bin/apt-get install sl
> SHELL=/bin/bash
> SUDO_USER=greg
> PWD=/tmp
> ====================================================================
> 
> Conclusion: there is nothing at all in the environment or arguments
> passed to the Post-Invoke script(s) that indicate what has been done.
> Any such scripts created by the local sysadmin will have to take their
> own investigative steps to try to figure out what happened, and what
> they should do about it.
> 
> Unless of course there's some *other* hook that we don't know about
> because the documentation is so poor.

Well, I just plagiarised /etc/apt/apt.conf.d/99needrestart:

  $ cat /etc/apt/apt.conf.d/99redogrub 
  DPkg::Post-Invoke {"test -x /var/local/bin/redo && /var/local/bin/redo || true"; };
  $ 

and wrote /var/local/bin/redo:

  $ cat /var/local/bin/redo 
  #!/bin/sh
  if [ "/boot/grub/grub.cfg" -nt "/var/local/bin/redo" ]; then
    grub-mkconfig -o /boot/grub/grub.cfg
  fi
  touch "/var/local/bin/redo"
  #
  $ 

Then with:

  $ ls -l /boot/grub/grub.cfg /var/local/bin/redo 
  -rw-r--r-- 1 root root  10634 May 22 21:27 /boot/grub/grub.cfg
  -rwxr--r-- 1 root staff   143 Jun 15 11:31 /var/local/bin/redo
  $  

uninstalling bash-doc and reinstalling it, nothing happened. But after:

  # touch /boot/grub/grub.cfg
  # 

then we get:

  # apt-get remove bash-doc
  Reading package lists... Done
  Building dependency tree... Done
  Reading state information... Done
  The following packages will be REMOVED:
    bash-doc
  0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.
  After this operation, 3318 kB disk space will be freed.
  Do you want to continue? [Y/n] 
  (Reading database ... 327723 files and directories currently installed.)
  Removing bash-doc (5.1-2+deb11u1) ...
  Processing triggers for install-info (6.7.0.dfsg.2-6) ...
  Processing triggers for doc-base (0.11.1) ...
  Processing 2 removed doc-base files...
  Invalid format pdf for bash (Bash Manual Page)
  Invalid format pdf for bash (Bash Manual Page)
  Registering documents with dhelp...
  Generating grub configuration file ...                ← voilà
  Found linux image: /boot/vmlinuz-5.10.0-35-amd64
  Found initrd image: /boot/initrd.img-5.10.0-35-amd64
  Found linux image: /boot/vmlinuz-5.10.0-34-amd64
  Found initrd image: /boot/initrd.img-5.10.0-34-amd64
  Warning: os-prober will be executed to detect other bootable partitions.
  Its output will be used to detect bootable binaries on them and create new boot entries.
  Found Debian GNU/Linux 10 (buster) on /dev/sda4
  Adding boot menu entry for UEFI Firmware Settings ...
  done
  # apt-get -o Acquire::http::Proxy="http://192.168.1.14:3142/"; install bash-doc
  Reading package lists... Done
  Building dependency tree... Done
  Reading state information... Done
  The following NEW packages will be installed:
    bash-doc
  0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
  Need to get 0 B/1931 kB of archives.
  After this operation, 3318 kB of additional disk space will be used.
  Retrieving bug reports... Done
  Parsing Found/Fixed information... Done
  Selecting previously unselected package bash-doc.
  (Reading database ... 327642 files and directories currently installed.)
  Preparing to unpack .../bash-doc_5.1-2+deb11u1_all.deb ...
  Unpacking bash-doc (5.1-2+deb11u1) ...
  Setting up bash-doc (5.1-2+deb11u1) ...
  Processing triggers for install-info (6.7.0.dfsg.2-6) ...
  Processing triggers for doc-base (0.11.1) ...
  Processing 2 added doc-base files...
  Registering documents with dhelp...
  Scanning processes...
  Scanning processor microcode...
  Scanning linux images...
  Running kernel seems to be up-to-date.
  The processor microcode seems to be up-to-date.
  No services need to be restarted.
  No containers need to be restarted.
  No user sessions are running outdated binaries.
  # 

So the script runs whenever grub.cfg gets updated. Note that
grub-install does not update grub.cfg, IIRC, but the script
can be triggered manually whenever necessary (as I did above).

Cheers,
David.


Reply to: