6
votes

I want to use Perl to detect the OS type.

For example:

Let's say I have an installer, in order to know which commands the installer needs to run. I'll have to detect what operating system is installed, for example Linux. Let's say it's Linux. Now which type of Linux?

  • Fedora
  • Ubuntu
  • CentOS
  • Debian
  • etc.

How would I do this?

6

6 Answers

6
votes

The first step is to check the output of the $^O variable.

If the output is for example

linux

you need more processing to detect which distribution is used.

See perldoc perlvar.

So far, you can run lsb_release -a to see which distribution is used.

If this command is not present, you can test the presence of files like:

/etc/debian_version # debian or debian based
/etc/redhat-release # rpm like distro

Other files tests examples: Detecting Underlying Linux Distro


Consider xaxes' solution too using the Linux::Distribution module to check the distribution.


If you want to detect the package manager, you can try this approach:

 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;
 }
5
votes

According to perlvar, either $OSNAME or $^O will give you the operating system. This is also equivalent to using $Config{'osname'} (see Config for more). A special note for Windows systems:

In Windows platforms, $^O is not very helpful: since it is always MSWin32 , it doesn't tell the difference between 95/98/ME/NT/2000/XP/CE/.NET. Use Win32::GetOSName() or Win32::GetOSVersion() (see Win32 and perlport) to distinguish between the variants.

In order to get the exact platform for a Linux box, you'll need to use a module like xaxes mentioned in his answer.

5
votes

Also, you can use Config (it's a core module). This is an example:

use Config;
print "$Config{osname}\n";
print "$Config{archname}\n";

On my Mac OS X, it prints:

darwin
darwin-2level
2
votes

To determine what OS your script is running on, you can use $^O:

print $^O

And Linux::Distribution to check for the 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";
}
1
votes

This works well on Redhat or CentOS easily adjustable to others...

# 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
votes

You may check file - /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};

Use other key if needed:

$ 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"