On Sun 07 Nov 2021 at 08:58:23 (-0500), Stefan Monnier wrote: > didier gaumet [2021-11-07 03:16:12] wrote: > > Le mardi 26 octobre 2021 à 09:25 -0400, Stefan Monnier a écrit : > > [...] > >> Think of it this way: currently, you can more or less figure out > >> which > >> packages you decided to install on your machine by going through the > >> list > >> of installed packages and filtering out all those that are marked as > >> "automatically" installed. > >> > >> But you can only manipulate this list indirectly, via `apt install` > >> and > >> `apt remove`. > > > > to have the list of all automatically installed packages: > > # apt-mark showauto > > > > to have the list of all manually installed packages: > > # apt-mark showmanual > > > > to verify if the package PACKAGE have been automatically installed > > # apt-mark showauto $PACKAGE > > > > to verify if the package PACKAGE have been manually installed > > # apt-mark showmanual $PACKAGE > > I'm not sure exactly what you mean to say with the above. > Of course, we can extract some kind of description of the current state > with APT commands, but it's quite different from having it inside a text > file that you edit. > > The differences include: > > - The list is "in your face". When I look at `apt-mark showmanual`, for > about half of the packages I vaguely remember explicitly installing > them at some point but don't need them any more, others I'm pretty sure > I never (consciously) installed manually.
I look at the list of packages I actually installed by using the command (that I keep up my sleeve): $ zgrep -i -h -e commandline $(reverse $(sort99 /var/log/apt/history*)) | \ grep -v -e 'upgrade$' -e 'autoremove$' | \ sed -e 's/Commandline: apt-get -o APT::Status-Fd=4 -o APT::Keep-Fds::=5 -o APT::Keep-Fds::=6 -q -y --no-remove/[d-i]/;s/Commandline: apt-get -o APT::Status-Fd=4 -o APT::Keep-Fds::=5 -o APT::Keep-Fds::=6 -q/[d-i]/;s/Commandline: apt-get -y/[bas]/;s/Commandline: apt-get/[man]/;' | \ less (Sorry about the long line.) It does depend on having sufficient history: $ grep -A1 log /etc/logrotate.d/apt /var/log/apt/term.log { rotate 60 -- /var/log/apt/history.log { rotate 60 $ The reverse() and sort99() just deal with the sort-order of rotated logs¹, grep removes uninteresting commands, and the sed filter tidies the output by taking advantage of the stereotype commands used at various stages: the installer, my personal list of "base" packages, and later, casual installs.² It's not the neatest output, but it would be simple to edit into a file that could replicate a system, or act as the basis for installing a new system from the next Debian revision. It certainly saves having to remember to update my Christensen-style machine log every time I install a package. > - The list file naturally lends itself to extensions: > - It could contain comments, so you could easily remove a package but > keeping a note about it so it's easy to re-add. > - It could contain conditional elements, so the same file could be > used on different machines that need slightly different > packages installed. > - It could contain additional information per package, such as whether > to install the recommended dependencies, some config information so you > don't get queried during install, some file renamings, a list of > "overrides" (to ignore a specific dependency and/or allow installing > officially mutually-exclusive packages), ... > > It fundamentally changes the way you think about it, I think. > > >> In contrast, with NixOS/Guix that list is available in a plain text > >> editable file. I'm not sure I'd call scheme a "plain text". Or do you mean something other than the file that commences with: (operating-system ;; ... > > in Debian there is /var/lib/apt/extended_states > > Not a fun read, tho. AFAICT it's just a verbose way to keep the set of > not-manually-installed packages, so it includes all the info I want to > be implicit ;-) > > Also, regarding "editable", I suspect that if you edit this file by hand > and introduce an error in there you're probably not going to get much > support ;-) I would agree. I did post a script last year that attempted to construct a list of top-level packages using dpkg-query. (It could be improved, I'm sure, by someone who knows their way around apt and dpkg introspection better than I do.) But it's obviously easier to construct/maintain a list of packages intentionally installed than to guess/"deduce" it from manipulation of the system's package list and dependencies. > > Perhaps (not sure) comparing on each machine the results of > > # apt-cache unmet > > could give you valuable info > > Thanks, I didn't know about this one. I'd not met unmet either. I'm not sure whether it meets any requirement for me. For example, it tells me: Package parl-desktop-world version 1.9.18 has an unmet dep: Depends: firefox-esr-l10n-as Depends: firefox-esr-l10n-en-za Depends: firefox-esr-l10n-mai Depends: firefox-esr-l10n-ml Depends: firefox-esr-l10n-or I don't think I'm a member of the constituency that finds this useful. It seems to examine the entire distribution rather than just the part that's installed here. ¹ reverse () { [ -z "$1" ] && printf '%s\n' "Usage: ${FUNCNAME[0]} arguments ... returns the arguments in reverse order. (Don't specify TOO many!) eg, less \$(${FUNCNAME[0]} filenames*)" 1>&2 && return 1; local j Filelist=("$@"); for ((j=${#Filelist[@]}; j>0; j-=1)) do printf '%s\n' "${Filelist[j-1]}"; done } sort99 () { [ -z "$1" ] && printf '%s\n' "Usage: ${FUNCNAME[0]} prefixNsuffix ... returns the arguments in numerical order of the unique embedded digits, which can include one item lacking any N. (Don't specify TOO many!) eg, less \$(${FUNCNAME[0]} logfilename*)" 1>&2 && return 1; local j Filelist Filenumber; Filelist=(); for j in "$@"; do Filenumber="$(tr -c -d '[:digit:]' <<<"$j")"; [[ $Filenumber = "" ]] && Filenumber=0; Filelist[$Filenumber]="$j"; done; printf '%s\n' "${Filelist[@]}" } ² My list of "base" packages uses "-y install", as it's a script. Cheers, David.