How can I detect the operating system in Perl?

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");

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();

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.