1

TL;DR: is there a way to "automatically" install any kept back packages? I know that apt-get dist-upgrade is too blunt of an instrument.

Details...

I have a bash script that runs (periodically) to keep Ubuntu Desktop VMs in a consistent state.

It does the usual apt-get update ... apt-get upgrade routine. Of course, there are the periodic kept-back packages.

I have addressed this up to now by adding the kept back packages to a manual list of apt-get install <whatever was kept back>. I have started exploring a way to make this less manual.

About the time I found myself (seriously) pondering how to refactor sudo apt-get -V upgrade | grep '=>' | grep -Ei '([A-Z]+(-)?)+' -o | sed 'N;s/\n/ /;' for readability, it occurred to me that perhaps there is a better way. (yes... I hadn't quite fixed the bugs in that line either)

The horribleness above was an attempt to pull out the (unversioned) kept back package names in order to pass them dynamically to apt-get install.

So, is there a better way to identify the kept back packages and install them via apt-get install?

1
  • well... I still hope that there is a better way, but [stackoverflow.com/questions/1251999/… showed me how to get sed doing what I want in my ugly line above: sudo apt-get -V upgrade | grep '=>' | grep -Ei '([A-Z]+(-)?)+' -o | sed ':a;N;$!ba;s/\n/ /g' isolates the names of the kept-back packages May 13, 2015 at 3:40

1 Answer 1

2

I did more noodling on the problem (and learned lots more about sed along the way). I'm not convinced that this is the best way, but it is a way. If anyone has a better way to do this, please answer, and I'll happily take your answeer.

sudo apt-get upgrade -s | sed -n '/back:/,/upgraded./p' | sed '1d;$d'

The -s option of apt-get upgrade indicates a dry-run rather than an actual install. I pipe the dry-run output text to sed, where magic happens. In sed, -n makes it quiet, so only what I tell it to print actually prints. The what to print is defined by a starting and ending regex. Start with a line matching "back:", and end with a line matching "upgraded.". The sed syntax was tricky at first... linuxcommando helped me grok the basic range-of-lines selection. That last p is telling sed "ok... print now".

The output of the first sed is something like:

The following packages were kept back:

thing1 thing2 newthing3

42 upgraded, 7 newly installed 1 to remove, and 3 not upgraded.

I pipe that to another, simpler sed that drops the first and last lines (1d;$d). Note, there are ways to do line offset magic in the first sed, but I felt that made the single sed too confusing. I'm ok using a second sed, which leaves just:

thing1 thing2 newthing3

And those are the kept-back packages to manually install.

kept_back_packages=$(sudo apt-get upgrade -s | sed -n '/back:/,/upgraded./p' | sed '1d;$d')
sudo apt-get install $kept_back_packages -y

(the -y is just an assume-yes for scripted apt-get).

Note:

when there are no kept back packages, this handles it all gracefully and does nothing. An empty string gets passed to apt-get install, and that's ok.

1
  • Note: use yes n | sudo apt-get upgrade to simply say "no" to initiating the upgrade. Much faster than a full dry run
    – Hamy
    Jun 10, 2018 at 23:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .