Automating apt-get update/upgrade/dist-upgrade/autoremove


Part of the power of Linux comes from being able to automate commonly recurring tasks. Part of the method for learning is to figure out how to automate your tasks. Thus, the genesis of this project was when I noticed the need to run sudo apt-get update and sudo apt-get upgrade around the time of wanting to install new packages.

##First step: “sup” in .bash_aliases

I started evolving a function in .bash_aliases that I called “sup”, short for “sudo update/upgrade”. The first iteration was simple:

sup () {
    sudo apt-get update
    sudo apt-get upgrade

Running “sup” and entering my password saved me a bit of time, although I still had to respond to prompts. Later, I added sudo apt-get autoremove; and then once I found out about sudo apt-get dist-upgrade, I added that, too.

Then I ran across sources that mentioned running another upgrade after running those for, and then I threw in a final autoremove for good measure.

Finally, I found a source that mentioned added the -y parameter would automatically accept any questions in most situations. I’m not totally clear on the nature of the sanity checking that would cause it to abort, but I figure it’s safe enough for a non-mission-critical system.

So my current function is as follows:

sup () {
	sudo apt-get update -y;
	sudo apt-get upgrade -y;
	sudo apt-get dist-upgrade -y;
	sudo apt-get autoremove -y;
	sudo apt-get upgrade -y;
	sudo apt-get autoremove -y;

That’s handy enough right there and already was saving me some time.

But then I thought¹ about automating it to run in the background when my computer was idle.

##Second step: crontab + automated sudo password

I put sup into ~/ Running it, I realized it asked me for my password. So I started looking around and found this:

HowTO: Sudoers Configuration

I ended up adding the following (via sudo visudo):

# apt-get stuff 
myusername ALL = NOPASSWD: /usr/bin/apt-get

(where “myusername” is my actual linux username)

I think I could lock it down further, but some attempts to do so failed, and for my situation (family LAN), it’s good enough.

I have an old computer, so I was thinking that perhaps I didn’t want to just blindly run it every hour, but rather perhaps run it only if the computer had been idle for an hour first. If I’m idle for an hour, in most cases it should be perfectly fine to run the updates.

After some googling, I found information about the package xprintidle, which when run, outputs the number of milliseconds the computer has been idle.

Finally, for testing I wanted notifications for what the script was doing so I could add in debugging information, and instead of tailing a log file, I wanted desktop notifications, which you can totally do (as I found from a previous project) using notify-send. And I figured even in production, it’d be nice to display a notification that lasted an hour (so it would disappear and be replaced by subsequent runs of the script automatically, with some small overlap) so I’d know it ran once I came back to my idle computer.

So this may not be the most well-written script (open to suggestions), but it’s what I’ve got right now, and in testing so far, it appears to work:


# Script to automatically check for and install updates via apt-get if computer
#	has been idle for at least an hour


if [[ "$idletime" -gt "$idleminimum" ]]; then
	notify-send -t 10000 "sup Checking for updates..."
	sudo apt-get update -y;
	sudo apt-get upgrade -y;
	sudo apt-get dist-upgrade -y;
	sudo apt-get autoremove -y;
	sudo apt-get upgrade -y;
	sudo apt-get autoremove -y;
	notify-send -t 3600000 "sup System updated..."

I put in a notify-send at the start of the updates just in case I happen to be looking at the idle computer at that time, but I suspect it’s rare I’ll see it. :smile:

##Crontab fun: gnome-schedule

I added it to crontab, but notify-send didn’t send notifications. Bummer. Apparently it needs some sort of x support. Luckily, I found gnome-schedule which gives a GUI front-end to crontab - which is nice anyway. One option for items is X Application, which causes it to wrap the crontab in a script that it generates for you automatically that appears to work perfectly in this application.

##To Do: Run more intelligently

My enthusiasm for adding features to this has currently run out, but when I get around to it again, I’ll figure out some way to log the last time I actually ran an update, and refrain from running it again if it’s been less than something like four hours.

Basically, this will allow the script to be triggered after 1-2 hours of idle time², but also not run the update if it’s checked for updates in the past few hours - so I won’t just hit the servers every hour after it starts until I come back.

But I haven’t started on that yet. I’m not sure if I’ll have to play with some sort of persistent bash variable, or touch a file somewhere or something. Meh. That’s why I’m putting it off. :slight_smile:

¹ And this is always a dangerous thing…

² since it’s scheduled to run on-the-hour via crontab, but only runs updates if idletime is more than one hour, so the actual time it takes after the computer becomes idle is time-to-next-hour + one hour, or between 1-2 hours