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

Re: Goal: a specialized inventory of installed packages



On Sun 05 Apr 2020 at 13:17:37 (-0500), Richard Owlett wrote:
> On 04/05/2020 12:00 PM, David Wright wrote:
> > On Sun 05 Apr 2020 at 10:30:41 (-0500), Richard Owlett wrote:
> > 
> > > I currently have a configuration of Stretch that meets most of my needs.
> > 
> > > I'm setting out to do an _extremely_ custom *minimal* install of Buster.
> > > The desired inventory shall list *ONLY* top level packages.
> > > [ E.G. if gfortran was purposely installed, the ~dozen packages
> > > installed because they were tagged as depends, recommends, or suggests
> > > wold *NOT* be listed. ]
> > > 
> > > Is there a suitable tool? [Synaptic's History menu item is closest
> > > I've found].
> > 
> > I assume that what you're after is a command like
> >    apt-get install a b c d …
> > where the list is the shortest that would install the said system.
> > 
> > In which case, I would presume the answer is no.
> > 
> > But it's not too onerous to write a script to parse the status file
> > (dpkg-query does the grunt work) and determine which packages are
> > not a [pre-]depends/recommends/suggests of any other. You may or
> > may not want to prune the resulting list, removing the names of any
> > packages that the d-i has no option but to install itself.
> > 
> > How kindly apt will take to be presented with such a list of packages
> > for installation at one sitting, I don't know.
> 
> I wasn't aiming for tool to automajically recreate an existing system.
> I was going more for a tool to allow me to visualize specifying what
> my new system would/should look like.
> 'apt-mark ...' seems to be aimed at my goals.
> Thanks.

Well, it does appear from your response, "I'll just do what the
installer thinks is an absolute minimal install and run 'apt-mark
showmanual' against it", that you're still enjoying doing installs,
so you can probably iterate towards a solution by by trying your
minimal list and seeing what results (comparing it with your
"reference" installation).

And it does appear from your other response that minimalism is more
important than function, if you exclude Recommends.

But in any case, I was assuming you wanted a reverse tool, to work out
which packages on your system are top-level, in the sense that they
are not dependent on any other package that you've installed.

I've just cannibalised a function that I use for kind of similar
purposes, because with being kept at home it seemed a good time to try
out bash's associative arrays. (I've always dropped into Python in the
past.) You might want to try it out: its default is to include
Recommends, but you can generate a longer list by using strict Depends.

It doesn't handle alternatives ( | is treated as , ) and it ignores
Pre-Depends. It also works ab initio, as if you had to drive the
d-i selection yourself. But one could modify it to merge in a
dpkg-query listing from a system that's untouched post-install.

It uses trash files (as I often do) rather than pipes so that you can
inspect partial results. As I say, it was just to get my hands dirty
with bash associative arrays. Strictly, they're not functionally
required here, but they're meant to be fast to search than a list
of an indexed array. Anyway:

function my-packages-toplevels {
    [ "$1" = "-?" ] && printf '%s\n' "Usage:	$FUNCNAME [Depends-only]
	lists the packages installed on this system that are not dependent (and,
	if lacking any argument, not recommended) by any other package." >&2 && return 1
    local -A Depsrecs
    local Pkg Format=' ${Depends} ${Recommends} \n'
    [ -n "$1" ] && Format=' ${Depends} \n'
    local Unique1="$(mktemp ${Uniquetrash:-/tmp}/$FUNCNAME-"$(date +%s)"-1some-XXXX)"
    local Unique2="$(mktemp ${Uniquetrash:-/tmp}/$FUNCNAME-"$(date +%s)"-2all-XXXX)"
    dpkg-query -W --showformat "$Format" | sed -e 's/([^)]\+)//g;s/,/ /g;s/|/ /g;s/[ ]\+/ /g;s/ /\n/g;' | sort -u | tail -n +2 >| "$Unique1"
    while IFS=$'\n' read -r Pkg; do
	Depsrecs["$Pkg"]="yes"
    done < "$Unique1"
    dpkg-query -W --showformat '${Package}\n' | sort >| "$Unique2"
    while IFS=$'\n' read Pkg; do
	[[ ! -n "${Depsrecs[$Pkg]}" ]] && printf '%s\n' "$Pkg"
    done < "$Unique2"
    return 0
}

Cheers,
David.


Reply to: