# Linux kernel version comparision method

**URL:** <https://community.unix.com/t/linux-kernel-version-comparision-method/344448>\
**Category:** Shell Programming and Scripting\
**Created:** [July 14, 2014, 10:30am UTC](https://community.unix.com/t/linux-kernel-version-comparision-method/344448 "2014-07-14T10:30:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![veeresh\_15](https://community.unix.com/letter_avatar/veeresh_15/32/6_449c533f586939b6e5f246632a46421f.png) [@veeresh\_15](https://community.unix.com/u/veeresh_15)\
**Post date:** [July 14, 2014, 10:30am UTC](https://community.unix.com/t/linux-kernel-version-comparision-method/344448/1 "2014-07-14T10:30:15Z")

</div>

Hi All,

I am preparing a precheck script for my oracle DB installation.

I am setting an expected version value, actual version can be greater than the expected version or equal to it.

I am using the below logic to test this.

```nohighlight
expected=2.6.32-279.el6.x86_64
received=$(uname -r)

min=$(echo -e $expected"\n"$received|sort -V|head -n 1)
if ["$min" = "$expected"];then
       echo "Installed Version is higher than Expected."
       echo "Passed."
else
       echo "== FAILED == Received output is not as expected."
fi

```

Usually this logic works fine in checking the kernel version.  
But recently i came across a server where the kernel version is little different

```nohighlight
uname -r
2.6.32-279.39.1.el6.x86_64

```

If you look at the output, its has an extra numbers i.e., 39.1.

Can some one help me how to check for such extra characters, because with the current logic it fails to compare when we have extra digits in any one of the values.

Also it would be great if someone can give me a kernel version naming standard for Red Hat Linux.

Regards,  
Veer

---

<div class="post-metadata">

**Author:** ![Chubler\_XL](https://community.unix.com/user_avatar/community.unix.com/chubler_xl/32/2077_2.png) [@Chubler\_XL](https://community.unix.com/u/Chubler_XL)\
**Post date:** [July 14, 2014, 7:10pm UTC](https://community.unix.com/t/linux-kernel-version-comparision-method/344448/2 "2014-07-14T19:10:27Z")

</div>

Can't help with the Red Hat Kernel version naming standard but this might help with this particular issue:

```nohighlight
expected=2.6.32-279.el6.x86_64
received=$(uname -r)

exp_ver=${expected//\.el6.*/}
re_ver=${received//\.el6.*/}

if [${#re_ver} -lt ${#received} -a "$re_ver" '>' "$ex_ver"]
then
    echo "Installed Version is higher than Expected."
    echo "Passed."
else
    echo "== FAILED == Received output is not as expected."
fi

```

---

<div class="post-metadata">

**Author:** ![veeresh\_15](https://community.unix.com/letter_avatar/veeresh_15/32/6_449c533f586939b6e5f246632a46421f.png) [@veeresh\_15](https://community.unix.com/u/veeresh_15)\
**Post date:** [July 15, 2014, 4:39am UTC](https://community.unix.com/t/linux-kernel-version-comparision-method/344448/3 "2014-07-15T04:39:07Z")

</div>

Thanks for your reply Chubler, I have couple of questions related to your code.

```nohighlight
exp_ver=${expected//\.el6.*/}
re_ver=${received//\.el6.*/}

```

I was not aware of cutting out the string this way, i used to use awk or sed, but this looks more simpler,can you please explain me the syntax?

```nohighlight
if [${#re_ver} -lt ${#received} -a "$re_ver" '>' "$ex_ver"]

```

In this if statement, you are using '\>' symbol for comaparision, why is the comparasion operator in quotes?

Regards,  
Veer

---

<div class="post-metadata">

**Author:** ![Chubler\_XL](https://community.unix.com/user_avatar/community.unix.com/chubler_xl/32/2077_2.png) [@Chubler\_XL](https://community.unix.com/u/Chubler_XL)\
**Post date:** [July 15, 2014, 6:01am UTC](https://community.unix.com/t/linux-kernel-version-comparision-method/344448/4 "2014-07-15T06:01:06Z")

</div>

Shell pattern substitution

This is the shell pattern substitution (man bash or man ksh should provide details for you). This is much more efficient that using sed or awk as it's internal to the shell and doesn't require loading an external executable before processing.

The substitution I supplied in my solution is a little misleading and could do with some improvement; although it does work for the supplied data.

1. The backslash in `\.` is unnecessary, the dot character does not need to be escaped - it will only match with it's self, question mark `?` is used to represent any single character
2. `//` is used to replace all occurrences within the string not just the first.
3. `.*` matches the literal dot followed by zero or more characters. In the example dot does follow el6, but those used to other regular expressions may interpret this as zero or more occurrences of any single character, not dot followed by zero or more characters.

I think a better pattern substitution would be `echo ${expected/.el6*/}`

String comparisons

Greater than and less than need to be escaped within [] context otherwise they are treated as redirection this is not the case with [[and]]. It's a matter of choice on using backslash or single quotes. the following are equivalent:

```nohighlight
["$a" \< "$b"]
["$a" '<' "$b"]
[["$a" < "$b"]]

```

---

<div class="post-metadata">

**Author:** ![veeresh\_15](https://community.unix.com/letter_avatar/veeresh_15/32/6_449c533f586939b6e5f246632a46421f.png) [@veeresh\_15](https://community.unix.com/u/veeresh_15)\
**Post date:** [July 18, 2014, 9:01am UTC](https://community.unix.com/t/linux-kernel-version-comparision-method/344448/5 "2014-07-18T09:01:22Z")

</div>

I think i figured out the code to compare kernel & rpm version's on Redhat Linux.  
Below is the code that i have written and tested for various RPM's & kernel version.

```nohighlight
expected_ver=2.6.32-279.el6.x86_64
received_ver=2.6.32-279.39.1.el6.x86_64

expected_v=$(echo $expected_ver|awk -F'.' '{if($NF ~ /[xi]*86/ && $(NF-1) ~ /el/) NF=NF-2; else if ($NF ~ /[xi]*86/ && $(NF-1) !~ /el/) NF=NF-1; else if ($NF ~ /el/) NF=NF-1; for (i=1;i<=NF;i++) printf $i".";}'|sed 's/.$//')

received_v=$(echo $received_ver|awk -F'.' '{if($NF ~ /[xi]*86/ && $(NF-1) ~ /el/) NF=NF-2; else if ($NF ~ /[xi]*86/ && $(NF-1) !~ /el/) NF=NF-1; else if ($NF ~ /el/) NF=NF-1; for (i=1;i<=NF;i++) printf $i".";}'|sed 's/.$//')

if ["$expected_v" = "$received_v"]; then
	echo "Installed Version is same than Expected."
    echo "Passed."
else
	min=$(echo -e $expected_v"\n"$received_v|sort -V|head -n 1)
	if ["$min" = "$expected"];then
       echo "Installed Version is higher than Expected."
       echo "Passed."
	else
       echo "== FAILED == Received output is not as expected."
	fi
fi

```

---

<div class="post-metadata">

**Author:** ![sedwards](https://community.unix.com/letter_avatar/sedwards/32/6_449c533f586939b6e5f246632a46421f.png) [@sedwards](https://community.unix.com/u/sedwards)\
**Post date:** [November 19, 2014, 1:28pm UTC](https://community.unix.com/t/linux-kernel-version-comparision-method/344448/6 "2014-11-19T13:28:01Z")

</div>

I'm only interested in the first 3 'number groups' but this could be expanded as needed:

```nohighlight
	declare -a TEMP2
	TEMP1=$(uname --kernel-release)
	TEMP2=(${TEMP1//[.-]/ })
	VERSION=$(((${TEMP2[0]} * 10000)\
		+ (${TEMP2[1]} * 100)\
		+ ${TEMP2[2]}))

```
