3

OK I have always had this problem. I want JUST the available updates listed in a file via bash script from a Linux system (RHEL or Fedora) using yum but I always have to deal with the Header information created which looks like this:

    Loaded plugins: XXXX-repo  XXXX-updates
                  : WWWWWW-repo  something-updates  QQQQQ-updates
     Updated packages
     package1.i686         1:234                  RHEL 6.5 updates
     package2.i686         1:234                  RHEL 6.5 updates
     package3.i686         1-234                  RHEL 6.5 updates
     package4.noarch       1.234                  RHEL 6.5 updates

All I want is a list of package1,package2, etc. which seems simple enough but it isn't because I can't just grep on "updates" or ":". Am I looking at this wrongly? Why would I not want to capture what updates were found in a script? Should I just update and check what has been updated instead? Thoughts?

PS> I can not use --noplugins option.

EDIT: So far I have come up with this,

     sudo yum check-update | grep "\." | awk '(NR >=1) {print $1;}' | grep '^[[:alpha:]]'

Basically grab the lines with a period in them, the first line, and make sure it first contains alpha letters. Perhaps over done but it seems to work.

Mike Q
  • 6,716
  • 5
  • 55
  • 62

5 Answers5

6

To only print lines following (but not including) "Updated packages"

yum check-update | awk 'p; /Updated packages/ {p=1}'

Note, on my Fedora system, a blank line separates the "header" from the list of updatable packages, so I would use awk 'p;/^$/{p=1}'

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • yours was close, I'm not sure who to award here... lol Thanks. Basically we can narrow down by lines which are not letters like so: yum check-update | grep -v plugins | awk '(NR >=1) {print $1;}' | grep '^[[:alpha:]]' – Mike Q May 16 '14 at 17:24
  • @MikeQ, awk can pretty much do whatever grep can do, you you can simplify: `yum check-update | awk '!/plugins/ && /^[[:alpha;]]/ {print $1}'` – glenn jackman May 16 '14 at 19:20
3

If you pipe the output above into awk using this command:

| awk '(NR >=4) {print $1;}'

You will get the following output

package1.i686
package2.i686
package3.i686
package4.noarch

The (NR >=4) tells awk to ignore the first three lines. The {print $1;} tells awk to print the first word of each line.

You can read here for more information on cutting stuff out after certain characters on each line. You can then use sed if stripping out everything after the . is important

| awk '(NR >=4) {print $1;}' | sed s/\.[^\.]*$// 

Gives the following output

package1
package2
package3
package4

Then pipe it into another sed command to replace the linebreaks with a comma.

| awk '(NR >=4) {print $1;}' | sed s/\.[^\.]*$// | sed ':a;N;$!ba;s/\n/,/g'

Yields the following output

package1,package2,package3,package4
Community
  • 1
  • 1
Jonathan Wheeler
  • 2,539
  • 1
  • 19
  • 29
  • This was very close to what I need. I think we want to do something like this to be more bulletproof: yum check-update | grep -v plugins | awk '(NR >=1) {print $1;}' | grep '^[[:alpha:]]' – Mike Q May 16 '14 at 17:25
  • You don't know for sure if the top header lines are going to be 1, 2 or say even 0 in l length. I want to give part credit, is that possible? – Mike Q May 16 '14 at 18:18
2

A more flexible solution

The solution below does not assume a specific number of lines in the Header (Ex. in CentOS I got much more header lines).
Nor does it suppose that you are only interested in the repository updates.

yum check-update | awk '/\S+\s+[0-9]\S+\s+\S+/ {print $1 }' > updates

Example

For the following yum check-update output

Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
epel/x86_64/metalink                    |  31 kB  00:00:00  
 * base: asi-fs-m.net
Excluding mirror: mirror.de.leaseweb.net
Excluding mirror: mirror.fra10.de.leaseweb.net
base                                    | 3.6 kB  00:00:00  
cwp                                     | 2.9 kB  00:00:00  
extras                                  | 3.4 kB  00:00:00  
mariadb                                 | 2.9 kB  00:00:00  
remi-safe                               | 3.0 kB  00:00:00  
updates                                 | 3.4 kB  00:00:00  
remi-safe/primary_db                    | 1.4 MB  00:00:00  

openvpn.x86_64          2.4.7-1.el7              epel  
polkit.x86_64           0.112-18.el7_6.1         updates  
pure-ftpd.x86_64        1.0.47-2.el7             epel  
remi-release.noarch     7.6-2.el7.remi           remi-safe

You can get

openvpn.x86_64
polkit.x86_64
pure-ftpd.x86_64
remi-release.noarch

Explanation

This solution assumes that the relevant lines have the pattern
<package name><spaces><version number><spaces><repo name>

If you want to output a particular repository, then use the pattern
/\S+\s+[0-9]\S+\s+repo_name/

PS:

If this solution does not work in your system, let me know in a comment

ePi272314
  • 12,557
  • 5
  • 50
  • 36
1

Try this:

yum check-update | awk '{if($5 ~ /updates/){print $1}}' | tr '\n' ','

If the input contains 'updates' on fifth column then print first column and create a csv list.

Tiago Lopo
  • 7,619
  • 1
  • 30
  • 51
  • This is not an overly secure way to do it.... not bad though, thanks for sharing .. . – Mike Q May 16 '14 at 18:19
  • @MikeQ, what do mean by 'overly secure way'? it may not be portable accross distros but it would always work on yours. :) – Tiago Lopo May 18 '14 at 13:36
1

Isn't this easier:

yum check-update -q | awk '{print $1}'

Edited.

The explanation of the command:

yum check-update -p - will list the updates in a 3 column list which are package + new version + repository.

awk '{ print $1 }' - will pick up the first column ( package )

smega
  • 11
  • 1
  • 3
  • Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Tyler2P Dec 08 '20 at 17:17