[TriLUG] detecting kernel major/minor versions
Aaron S. Joyner
aaron at joyner.ws
Fri Jun 30 03:27:57 EDT 2006
Rick DeNatale wrote:
> On 6/26/06, Benjamin Reed <rangerrick at befunk.com> wrote:
>
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Joseph Mack NA3T wrote:
>>
>> > uname_r=`uname -r`
>> > minor_and_subminor=${uname_r##*2.6.}
>> > minor=${minor_and_subminor%\.*}
>>
>> Bash stuff works, although this will fail when 2.7 comes out... <grin>
>>
>> I generally use "cut" for such things, it tends to be more future-proof:
>>
>> minor_and_subminor=`echo $uname_r | cut -d. -f3-`
>> minor=`echo $uname_r | cut -d. -f3`
>>
>> - -d. means chop up the string on the "."s
>> - -f3 means display the 3rd entry in the chopped string
>> - -f3- means display the 3rd entry and anything afterwards
>>
>> you could also do "-f3-4" to specifically ask for the 3rd through the
>> 4th.
>
>
> Teacher! Teacher!
>
> I'm missing something here, in my case both forms of the -f parm give
> the same results:
>
> rick at bill:~$ uname -r
> 2.6.15-25-686
> rick at bill:~$ uname -r | cut -d. -f3-
> 15-25-686
> rick at bill:~$ uname -r | cut -d. -f3
> 15-25-686
When you want to match a pattern, it's hard to beat regular
expressions. I'll start simple:
asjoyner at bob:~$ uname -r | cut -d. -f3-
15-1-686-smp
asjoyner at bob:~$ uname -r | sed -e 's/[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/'
15
This matches all occurances of 3 sets of numbers followed by dots, up
the first thing that's not a number after the start of the 3rd set,
takes what that defines as the 3rd set, and throws away the rest. To
get a better / simpler regex than this, you need to use non-greedy
regex's, which requires a better regex engine, ala perl:
asjoyner at bob:~$ echo 200a.633\!.15-foo | sed -e
's/[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/'
200a.633!.15-foo
asjoyner at bob:~$ echo 200a.633\!.15-foo | perl -pe
's/^.*?\..*?\.([0-9]+).*/$1/'
15
This says, take all occurances of anything up to the first dot (but no
farther), then the same to the second dot, then grab all the following
digits, and throw away everything but those digits. It will parse
things that choke and confuse the sed, such as the first version sed
above. I wonder if we can use negation in the character ranges to come
up with something almost as good in sed...
asjoyner at bob:~$ echo 200a.633\!.15-foo | sed -e
's/[^.]*\.[^.]*\.\([0-9]*\).*/\1/'
15
Yep, this regex says, take everything which is *not* a dot, up to the
first dot, repeat to the 2nd dot, then grab the digits, and throw away
everything else. This is roughly equivalent to the perl expression
above, and perhaps the most readable and simplest of all.
Ah, fun with regexs. Can anyone come up with a pattern that looks
remotely like a version number that the above perl or sed won't match?
How about a better / simpler / easier-on-the-eyes pattern?
Aaron S. Joyner
More information about the TriLUG
mailing list