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: