使用Perl检测操作系统类型

6
我想使用Perl来检测操作系统类型。
例如:假设我有一个安装程序,为了知道安装程序需要运行哪些命令。我必须检测已安装的操作系统,例如Linux。 假设它是Linux。 现在是哪种类型的Linux?
- Fedora - Ubuntu - CentOS - Debian - 等等
我该如何做到这一点?
6个回答

6
第一步是检查$^O变量的输出。
如果输出例如

linux

你需要更多的处理来检测使用了哪个发行版。
参见perldoc perlvar
到目前为止,你可以运行lsb_release -a来查看使用了哪个发行版。
如果不存在这个命令,你可以测试文件是否存在,例如:
/etc/debian_version # debian or debian based
/etc/redhat-release # rpm like distro

其他文件测试示例:检测底层Linux发行版


还可以考虑使用 xaxes的解决方案,使用Linux::Distribution 模块来检查发行版。


如果要检测软件包管理器,可以尝试以下方法:

 if ($^O eq "linux") {
     my $pm;

     do{
         if (-x qx(type -p $_ | tr -d "\n")) {
             $pm = $_;
             last;
         }
     } for qw/apt-get aptitude yum emerge pacman urpmi zypper/;

     print $pm;
 }

2
应该是 $^O(大写字母 O),而不是零。 - Jonah Bishop

5
此外,您可以使用Config(它是一个核心模块)。以下是一个示例:
use Config;
print "$Config{osname}\n";
print "$Config{archname}\n";

在我的Mac OS X上,它打印出:
darwin
darwin-2level

5
根据 perlvar$OSNAME$^O 可以告诉你操作系统的信息。这也相当于使用 $Config{'osname'}(有关更多信息,请参见 Config)。对于 Windows 系统来说,需要特别注意:

在 Windows 平台上,$^O 并不是非常有用:由于它始终为 MSWin32,无法区分 95/98/ME/NT/2000/XP/CE/.NET。需要使用 Win32::GetOSName()Win32::GetOSVersion()(有关详细信息,请参见 Win32perlport)来区分不同的 Windows 变体。

要获取 Linux 系统的确切平台信息,需要使用像 xaxes 在他的答案中提到的模块。

例如在Windows中,如果我执行了$^O,并且它显示为"windows",那么我可以这样做:if $^O eq 'MSWin32',然后执行Win32::GetOSVersion()吗? - StackedFlow
没错。记得在脚本顶部使用 use Win32 - Jonah Bishop

2

要确定脚本运行的操作系统,可以使用$^O

print $^O

使用 Linux::Distribution 来检查发行版:

use Linux::Distribution qw(distribution_name distribution_version);

my $linux = Linux::Distribution->new;
if (my $distro = $linux->distribution_name()) {
      my $version = $linux->distribution_version();
      print "you are running $distro, version $version\n";
} else {
      print "distribution unknown\n";
}

是的,但如果是Linux系统,那就很好了,但要如何获取确切的名称以确定是否使用apt-get或yum呢? - StackedFlow
检查软件包管理器列表怎么样?foreach $manager (@package_manager) { $check = $manager; } [在这里检查$check包含了什么] - xaxes

1
这在Redhat或CentOS上很好用,很容易适应其他系统...
# Test for release file
my $release_file="";
if ( -e "/etc/redhat-release" ) {
  $release_file="/etc/redhat-release";
} elsif ( -e "/etc/centos-release" ) {
  $release_file="/etc/centos-release";
} elsif ( -e "/etc/system-release" ) {
  $release_file="/etc/system-release";
} else {
  print "OS Release file missing, can't determine version information";
  exit;
}

my $OS_NAME=`cat $release_file|cut -d " " -f1`;
my $OS_MAJOR_VERSION=`sed -rn 's/^[^0-9]*([0-9]+)\\.[0-9]+.*/\\1/p' $release_file`;
my $OS_MINOR_VERSION=`sed -rn 's/^[^0-9]*[0-9]+.([0-9]+).*/\\1/p' $release_file`;

chomp($OS_NAME);
chomp($OS_MAJOR_VERSION);
chomp($OS_MINOR_VERSION);

print "\nOS Name and Version: ${OS_NAME} ${OS_MAJOR_VERSION}.${OS_MINOR_VERSION}\n\n";

0
您可以检查文件 - /etc/os-release:
#!/usr/bin/perl

use feature(say);
use strict;
use warnings;


my %os=();

unless ( open(OS,"cat /etc/os-release|") ){
        say "ErrorOpenPipe OS_release";
        exit;
}

while (<OS>){
        my @os_param = split /=/, $_;
        $os{$os_param[0]}=$os_param[1];
}


my @FH;

say $os{ID};
say $os{VERSION_ID};

如有需要,请使用其他键:

$ cat /etc/os-release 

NAME="Ubuntu"
VERSION="16.04.5 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.5 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

$ cat /etc/os-release 

NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接