Det
Det

Reputation: 3710

How to determine the latest major and full kernel version string as compactly as possible

So what I'm intending to do here is to determine both the latest major and the full kernel version string as compactly as possible (without a zillion pipes to grep).

I'm already quite content with the result but if anybody has any ideas how to squash the first line even the slightest it'd be very awesome (it has to work when there are no minor patches as well).

The index of kernel.org is only 36kB compared to the 136kB of that of http://www.kernel.org/pub/linux/kernel/v3.x/ so that's why I'm using it:

_major=$(curl -s http://www.kernel.org/ -o /tmp/kernel && cat /tmp/kernel | grep -A1 mainline | tail -1 | cut -d ">" -f3 | cut -d "<" -f1) 
pkgver=${_major}.$(cat /tmp/kernel | grep ${_major} | head -1 | cut -d "." -f6)

Upvotes: 4

Views: 954

Answers (4)

eschwartz
eschwartz

Reputation: 323

Expanding on @Justin Brewer's answer, you probably want to know when a kernel is EOL since this is useful information... the following single awk command preserves all this information for you.

latest_kernel() {
    curl -s https://www.kernel.org/finger_banner |awk -F ':' -v search="$1" '{if ($1 ~ search) {gsub(/^[ ]+/, "", $2); print $2}}'
}
  • -F ':' -- field separator because everything after the : is the version string.
  • -v search="$1" -- pass search string as an awk internal variable
  • if statement -- check if field $1 matches the search string
  • gsub -- in-place modify of field $2 to strip leading spaces

Then just print field $2 for any matching records (I presume your search string will only match the left-hand side of one line... if it is important to exit after the first match, use print $2; exit)

Search string can include spaces, etc. Use of awk variables and matching with ~ variable instead of pattern-matching '.../'"$1"'/...' avoids the need to exit single-quote mode and avoids syntax errors where the search string contains "/".

Upvotes: 0

Justin Brewer
Justin Brewer

Reputation: 41

kernel.org provides a plaintext listing of all the current versions at https://www.kernel.org/finger_banner

For mainline:

curl -s https://www.kernel.org/finger_banner | grep mainline | awk '{print $NF}'

For latest stable:

curl -s https://www.kernel.org/finger_banner | grep -m1 stable | awk '{print $NF}'

The mainline and latest stable versions will never be EOL, but other versions often are, so the above awk commands will not work correctly for all versions. A general solution as a bash function:

latest_kernel() {
    curl -s https://www.kernel.org/finger_banner | grep -m1 $1 | sed -r 's/^.+: +([^ ]+)( .+)?$/\1/'
}

Examples:

$ latest_kernel mainline
4.18-rc2
$ latest_kernel stable
4.17.3
$ latest_kernel 4.16
4.16.18

Upvotes: 3

Smylers
Smylers

Reputation: 1713

You've got a useless use of cat. You can replace:

cat /tmp/kernel | grep -A1 mainline

with simply:

grep -A1 mainline /tmp/kernel

In your case, you don't even need the file at all. Curl by default will emit to standard output, so you can just do:

curl -s http://www.kernel.org/ | grep -A1 mainline

Upvotes: 1

dwurf
dwurf

Reputation: 12749

It's just a thought exercise at this stage as the real answer is in the comments above, but here are some possible improvements.

Original:

_major=$(curl -s http://www.kernel.org/ -o /tmp/kernel && cat /tmp/kernel | grep -A1 mainline | tail -1 | cut -d ">" -f3 | cut -d "<" -f1)

Use tee instead of cat:

_major=$(curl -s http://www.kernel.org/ | tee /tmp/kernel | grep -A1 mainline | tail -1 | cut -d ">" -f3 | cut -d "<" -f1)

Use sed to minimise the number of pipes, and to make the command unreadable

_major=$(curl -s http://www.kernel.org/ | tee /tmp/kernel | sed -n '/ainl/,/<\/s/ s|.*>\([0-9\.]*\)</st.*|\1|p')

Cheap tricks: shorten the URL

_major=$(curl -s kernel.org | tee /tmp/kernel | sed -n '/ainl/,/<\/s/ s|.*>\([0-9\.]*\)</st.*|\1|p')

Upvotes: 3

Related Questions