如何在 perl 中列出内核的最高版本
How can I list highest version of a kernel in perl
在许多 docker 容器中,文件 /boot 是空的。不过,vmlinuz 在 /var/lib/modules//vmlinuz
中可用
在shell,我能做到:
for kver in $(ls /lib/modules|sort -Vr)
do
test -f /lib/modules/$kver/vmlinuz && echo $kver && break
done
我如何以可靠的方式在 perl 中执行此操作(我的意思是:使用 CentOS-6 到 CentOS-8 或任何其他 Linux 发行版中的模块。
我已经看到用于内核版本比较或版本排序的模块,但是 none 在 CentOS 的所有版本中都可以作为发行包使用,范围从 6 到 8 包括(8 很重要,因为它是RHEL-8 和 RHEL-8 是关于 perl 软件包的极其精简的发行版。
如果我有这两个版本:4.18.0-144.el8.x86_64 4.18.0-80.7.1.el8_0.x86_64 我需要选择 - 144个.
最简单的方法是使用 Sort::Versions 模块(您需要从 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;
}
}
更新:您的问题包括:
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
当然,安装包并不是安装 CPAN 模块的唯一方式。您始终可以使用 cpan
或 cpanm
。但是如果您真的不想那样安装模块,那么您也可以将 versioncmp()
子例程剪切并粘贴到您的代码中。只有几十行代码。
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;
}
在 perl 中使用 ls
是作弊吗?
for (`ls -rv /lib/modules/`){
chomp;
next unless -e "/lib/modules/$_/vmlinuz";
say;
last;
}
在许多 docker 容器中,文件 /boot 是空的。不过,vmlinuz 在 /var/lib/modules/
在shell,我能做到:
for kver in $(ls /lib/modules|sort -Vr)
do
test -f /lib/modules/$kver/vmlinuz && echo $kver && break
done
我如何以可靠的方式在 perl 中执行此操作(我的意思是:使用 CentOS-6 到 CentOS-8 或任何其他 Linux 发行版中的模块。
我已经看到用于内核版本比较或版本排序的模块,但是 none 在 CentOS 的所有版本中都可以作为发行包使用,范围从 6 到 8 包括(8 很重要,因为它是RHEL-8 和 RHEL-8 是关于 perl 软件包的极其精简的发行版。
如果我有这两个版本:4.18.0-144.el8.x86_64 4.18.0-80.7.1.el8_0.x86_64 我需要选择 - 144个.
最简单的方法是使用 Sort::Versions 模块(您需要从 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;
}
}
更新:您的问题包括:
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
当然,安装包并不是安装 CPAN 模块的唯一方式。您始终可以使用 cpan
或 cpanm
。但是如果您真的不想那样安装模块,那么您也可以将 versioncmp()
子例程剪切并粘贴到您的代码中。只有几十行代码。
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;
}
在 perl 中使用 ls
是作弊吗?
for (`ls -rv /lib/modules/`){
chomp;
next unless -e "/lib/modules/$_/vmlinuz";
say;
last;
}