skip to Main Content

In many docker container, le /boot is empty. Though, the vmlinuz is available in /var/lib/modules/<kver>/vmlinuz

In shell, I can do:

for kver in $(ls /lib/modules|sort -Vr)
do
    test -f /lib/modules/$kver/vmlinuz && echo $kver && break
done

How can I do this un perl in a reliable way (I mean: using modules that are present in CentOS-6 to CentOS-8 or any other Linux distro.

I’ve seen that modules for kernel version comparison or version sorting, but none are available as distro package in all release of CentOS ranging from 6 to 8 included (8 is important as it s a clone of RHEL-8 and RHEL-8 is extremely stripped down distro regarding perl packages).

If I have those 2 versions: 4.18.0-144.el8.x86_64 4.18.0-80.7.1.el8_0.x86_64 I need to chose the -144 one.

2

Answers


  1. The easiest way to do this would be to use the Sort::Versions module (which you’d need to install from CPAN).

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use feature 'say';
    
    use Sort::Versions;
    use File::Basename;
    
    for (sort { versioncmp($b, $a) } glob '/lib/modules/*') {
      my $ver = basename $_;
      if (-e "/lib/modules/$ver/vmlinuz") {
        say $ver;
        last;
      }
    }
    

    Update: Your question includes this:

    I’ve seen that modules for kernel version comparison or version sorting, but none are available as distro package in all release of CentOS ranging from 6 to 8 included

    Of course, packages aren’t the only way to install CPAN modules. You could always use cpan or cpanm. But if you really don’t want to install a module that way, then you could also cut and paste the versioncmp() subroutine into your code. It’s only a few dozen lines of code.

    sub versioncmp ($$) {
        my @A = ($_[0] =~ /([-.]|d+|[^-.d]+)/g);
        my @B = ($_[1] =~ /([-.]|d+|[^-.d]+)/g);
    
        my ($A, $B);
        while (@A and @B) {
            $A = shift @A;
            $B = shift @B;
            if ($A eq '-' and $B eq '-') {
                next;
            } elsif ( $A eq '-' ) {
                return -1;
            } elsif ( $B eq '-') {
                return 1;
            } elsif ($A eq '.' and $B eq '.') {
                next;
            } elsif ( $A eq '.' ) {
                return -1;
            } elsif ( $B eq '.' ) {
                return 1;
            } elsif ($A =~ /^d+$/ and $B =~ /^d+$/) {
                if ($A =~ /^0/ || $B =~ /^0/) {
                    return $A cmp $B if $A cmp $B;
                } else {
                    return $A <=> $B if $A <=> $B;
                }
            } else {
                $A = uc $A;
                $B = uc $B;
                return $A cmp $B if $A cmp $B;
            }       
        }
        @A <=> @B;
    }
    
    Login or Signup to reply.
  2. Is it cheating to use ls within perl?

    for (`ls -rv /lib/modules/`){
      chomp;
      next unless -e "/lib/modules/$_/vmlinuz";
      say; 
      last;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search