If you use Debian Linux derivatives, specially Ubuntu, you probably noticed when you login it will tell you (using the MOTD) that there are new updates waiting for you. And, you can use that if, say, you are writing a script to let you know about that; someone I know use that to monitor his Ubunu boxes in Nagios. But, what about in RedHat and derviatives the lazy way?
Let's do some thinking aloud and see if we can come up with something. We know that if we run yum check-update, it should reply with the list of packages needing to be upgraded if any
[root@vmhost ~][raub@duckwitch ~]$ yum check-update Loaded plugins: fastestmirror Determining fastest mirrors * base: mirror.supremebytes.com * extras: mirror.hostduplex.com * updates: mirror.scalabledns.com chkconfig.x86_64 1.3.61-5.el7_2.1 updates device-mapper.x86_64 7:1.02.107-5.el7_2.5 updates device-mapper-libs.x86_64 7:1.02.107-5.el7_2.5 updates dracut.x86_64 033-360.el7_2.1 updates glibc.x86_64 2.17-106.el7_2.6 updates glibc-common.x86_64 2.17-106.el7_2.6 updates iproute.x86_64 3.10.0-54.el7_2.1 updates kernel.x86_64 3.10.0-327.22.2.el7 updates kpartx.x86_64 0.4.9-85.el7_2.5 updates libxml2.x86_64 2.9.1-6.el7_2.3 updates ntpdate.x86_64 4.2.6p5-22.el7.centos.2 updates pcre.x86_64 8.32-15.el7_2.1 updates selinux-policy.noarch 3.13.1-60.el7_2.7 updates selinux-policy-targeted.noarch 3.13.1-60.el7_2.7 updates systemd.x86_64 219-19.el7_2.11 updates systemd-libs.x86_64 219-19.el7_2.11 updates systemd-python.x86_64 219-19.el7_2.11 updates systemd-sysv.x86_64 219-19.el7_2.11 updates tzdata.noarch 2016f-1.el7 updates [raub@duckwitch ~]$
As you can see, it does not require you to run that command as root. And you can even check if a repo you use but configured to be normally disabled, like epel in the following example:
raub@duckwitch ~]$ yum check-update --enablerepo=epel Loaded plugins: fastestmirror epel/x86_64/metalink | 11 kB 00:00 epel | 4.3 kB 00:00 (1/3): epel/x86_64/group_gz | 170 kB 00:00 (2/3): epel/x86_64/updateinfo | 584 kB 00:00 (3/3): epel/x86_64/primary_db | 4.2 MB 00:00 Loading mirror speeds from cached hostfile * base: mirror.supremebytes.com * epel: mirror.chpc.utah.edu * extras: mirror.hostduplex.com * updates: mirror.scalabledns.com chkconfig.x86_64 1.3.61-5.el7_2.1 updates device-mapper.x86_64 7:1.02.107-5.el7_2.5 updates device-mapper-libs.x86_64 7:1.02.107-5.el7_2.5 updates dracut.x86_64 033-360.el7_2.1 updates epel-release.noarch 7-7 epel glibc.x86_64 2.17-106.el7_2.6 updates glibc-common.x86_64 2.17-106.el7_2.6 updates iproute.x86_64 3.10.0-54.el7_2.1 updates kernel.x86_64 3.10.0-327.22.2.el7 updates kpartx.x86_64 0.4.9-85.el7_2.5 updates libxml2.x86_64 2.9.1-6.el7_2.3 updates ntpdate.x86_64 4.2.6p5-22.el7.centos.2 updates pcre.x86_64 8.32-15.el7_2.1 updates selinux-policy.noarch 3.13.1-60.el7_2.7 updates selinux-policy-targeted.noarch 3.13.1-60.el7_2.7 updates systemd.x86_64 219-19.el7_2.11 updates systemd-libs.x86_64 219-19.el7_2.11 updates systemd-python.x86_64 219-19.el7_2.11 updates systemd-sysv.x86_64 219-19.el7_2.11 updates tzdata.noarch 2016f-1.el7 updates [raub@duckwitch ~]$
What if there are no upgrades?
[root@server1 ~]# yum check-update Loaded plugins: fastestmirror base | 3.6 kB 00:00 extras | 3.4 kB 00:00 updates | 3.4 kB 00:00 Loading mirror speeds from cached hostfile * base: mirror.us.leaseweb.net * extras: mirror.us.leaseweb.net * updates: reflector.westga.edu [root@server1 ~]#
Sounds like we need to check for the first blank line. We can do that using sed. We can find the blank line by using the /^\s*$/ search pattern in sed. So we could start with something like (the -n is there because we only care when we find said blank line)
yum check-update | `sed -n '/^\s*$/p'`
which if you run does not seem to do much. Reason is that what we really want is to know if the match was successful or not. And, sed actually has the answer: look at these entries I stole from its man pange:
q [exit-code] Immediately quit the sed script without processing any more input, except that if auto-print is not disabled the current pattern space will be printed. The exit code argument is a GNU extension. Q [exit-code] Immediately quit the sed script without processing any more input. This is a GNU extension.
Let's try it then. First we will find a machine that has a package that needs to be updated. In this case it will be my KVM server, which you have met before when we talked about USB passthrough:
[raub@vmhost ~]$ yum check-update Loaded plugins: fastestmirror, security Loading mirror speeds from cached hostfile * base: mirror.vcu.edu * extras: centos.mirror.constant.com * updates: mirror.vcu.edu samba4-libs.x86_64 4.2.10-7.el6_8 updates [raub@vmhost ~]$[raub@vmhost ~]$ yum check-update | `sed -n '/^\s*$/q1'` ; echo $? 1 [raub@vmhost ~]$So as of this writing it has one update. We then try our one-liner, which we want to return 0 if it did not find any pending upgrades and 1 if it did. And that is done by adding q1 past the search string, as in /^\s*$/q1, which means write 1 if search successful. Of course we now need to print the result, which can be done with echo $?. So, let's try it:
It thinks that it found it. I am not completely sure it works, so we need also to verify it works as it should when we find no updates:
[root@server1 ~]# yum check-update Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: mirror.netdepot.com * extras: mirror.solarvps.com * updates: ftpmirror.your.org [root@server1 ~]# yum check-update | `sed -n '/^\s*$/q1'` ; echo $? 0 [root@server1 ~]#
Sounds like we have a winner. Now all that is left is to wrap something around it to something with that. I will leave that to you. Note that it does not differentiate between normal and security updates though.