How can I detect the operating system in Perl?

Viewed 69582

I have Perl on Mac, Windows and Ubuntu. How can I tell from within the script which one is which? Thanks in advance.

Edit: I was asked what I am doing. It is a script, part of our cross-platform build system. The script recurses directories and figures out what files to build. Some files are platform-specific, and thus, on Linux I don't want to build the files ending with _win.cpp, etc.

11 Answers

Examine the $^O variable which will contain the name of the operating system:

print "$^O\n";

Which prints linux on Linux and MSWin32 on Windows.

You can also refer to this variable by the name $OSNAME if you use the English module:

use English qw' -no_match_vars ';
print "$OSNAME\n";

According to perlport, $^O will be darwin on Mac OS X.


You can also use the Config core module, which can provide the same information (and a lot more):

use Config;

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

Which on my Ubuntu machine prints:

linux
i486-linux-gnu-thread-multi

Note that this information is based on the system that Perl was built, which is not necessarily the system Perl is currently running on (the same is true for $^O and $OSNAME); the OS won't likely be different but some information, like the architecture name, may very well be.

If you need more specific information on Windows this may help.

my $osname = $^O;


if( $osname eq 'MSWin32' ){{
  eval { require Win32; } or last;
  $osname = Win32::GetOSName();

  # work around for historical reasons
  $osname = 'WinXP' if $osname =~ /^WinXP/;
}}

Derived from sysinfo.t, which I wrote the original version.

If you need more detailed information:

my ( $osvername, $major, $minor, $id ) = Win32::GetOSVersion();

Look inside the source for File::Spec to see how it loads the right delegate based on the operating system. :)

File::Spec has a separate Perl module file for each OS. File::Spec::Win32, File::Spec::OS2, etc...

It checks the operating system and will load the appropriate .pm file at runtime based on OS.

# From the source code of File::Spec
my %module = (
      MSWin32 => 'Win32',
      os2     => 'OS2',
      VMS     => 'VMS',
      NetWare => 'Win32', # Yes, File::Spec::Win32 works on NetWare.
      symbian => 'Win32', # Yes, File::Spec::Win32 works on symbian.
      dos     => 'OS2',   # Yes, File::Spec::OS2 works on DJGPP.
      cygwin  => 'Cygwin',
      amigaos => 'AmigaOS');


my $module = $module{$^O} || 'Unix';

require "File/Spec/$module.pm";
our @ISA = ("File::Spec::$module");

Sys::Info::OS looks like a relatively clean potential solution, but currently doesn't seem to support Mac. It shouldn't be too much work to add that though.

The variable $^O (that's a capital 'O', not a zero) holds the name of the operating system.

Depending on what you want, it may or may not give the answer you want - on my system it gives 'linux' without saying which distro. I'm not so sure about what it says on Windows or MacOS.

Here's a quick reference on how to find the OS the local machine is running from Perl.

The $^O variable ($OSTYPE if you use English) contains the operating system that your perl binary was built for.

FYI on Mac computers $^O now returns 'darwin' for 10.13.6 (High Sierra) and 10.15.4 (Catalina).

For a generic mapping from a CPAN module, check out Perl::OSType.

It's used by Module::Build.

By "generic mapping," it returns a value from a much smaller set of OS identifiers - in most cases, that's probably more useful ($^O can return over 50 values). Looking at the source, the possible return values are only

Unix
Windows
EBCDIC
MacOS
VMS
VOS
RiscOS
Amiga
MPEiX

The module has admittedly not been updated for over 5 years, and based on @brian-d-foy's answer, OS2 is notably missing. Also, if you are looking to use File::Spec, his answer is probably better for that use case.

Related