我在 Mac、Windows 和 Ubuntu 上都有 Perl。如何在脚本内部区分它们?
编辑:有人问我在干什么。这是一个脚本,是我们跨平台构建系统的一部分。该脚本递归遍历目录并确定要构建哪些文件。某些文件是特定于某些平台的,因此,在 Linux 上,我不想构建以 _win.cpp 结尾的文件等。
我在 Mac、Windows 和 Ubuntu 上都有 Perl。如何在脚本内部区分它们?
编辑:有人问我在干什么。这是一个脚本,是我们跨平台构建系统的一部分。该脚本递归遍历目录并确定要构建哪些文件。某些文件是特定于某些平台的,因此,在 Linux 上,我不想构建以 _win.cpp 结尾的文件等。
查看$^O
变量,它将包含操作系统的名称:
print "$^O\n";
该程序在Linux系统上打印linux
,在Windows系统上打印MSWin32
。
如果您使用English模块,也可以通过名称$OSNAME
引用此变量:
use English qw' -no_match_vars ';
print "$OSNAME\n";
$^O
将会是 darwin
。
use Config;
print "$Config{osname}\n";
print "$Config{archname}\n";
在我的Ubuntu机器上运行该命令,结果如下:
linux
i486-linux-gnu-thread-multi
$^O
和$OSNAME
同样如此)。操作系统可能不会改变,但某些信息(例如架构名称)可能会发生变化。STDOUT_TOP0
而暂时被困住,请确保使用的是$^O
而不是$^0
。我不能告诉你我是怎么知道这个的,但请相信我... - Anthonymy $osname = $^O;
if( $osname eq 'MSWin32' ){{
eval { require Win32; } or last;
$osname = Win32::GetOSName();
# work around for historical reasons
$osname = 'WinXP' if $osname =~ /^WinXP/;
}}
这段文字来源于sysinfo.t,它是我编写的原始版本。
如果您需要更详细的信息:
my ( $osvername, $major, $minor, $id ) = Win32::GetOSVersion();
File::Spec
源代码,了解它如何根据操作系统加载正确的代理。
File::Spec
为每个操作系统单独提供了一个Perl模块文件,例如File::Spec::Win32
、File::Spec::OS2
等。
它检查操作系统,并在运行时基于操作系统加载适当的.pm
文件。
# 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 看起来是一个相对干净的潜在解决方案,但目前似乎不支持 Mac。不过添加支持应该不会太麻烦。
变量 $^O(注意是大写字母 O,不是数字 0)保存操作系统的名称。
根据您所需,它可能会或可能不会给出您想要的答案 - 在我的系统上,它给出“linux”,但没有指明哪个发行版。我不太确定它在 Windows 或 MacOS 上的表现如何。
关于 Mac 计算机的信息:$^O
现在返回 'darwin',适用于 10.13.6(High Sierra)、10.15.4(Catalina)...以及 13.4(Ventura)。
一个经典的单行代码:
my $windows=($^O=~/Win/)?1:0;# Are we running on windows?
如果需要一个通用的CPAN模块映射,请查看Perl::OSType
。
它被Module::Build
使用。
所谓“通用映射”,它返回一个较小的操作系统标识符集合中的值 - 在大多数情况下,这可能更有用($^O
可以返回50多个值)。查看源代码,可能的返回值只有
Unix
Windows
EBCDIC
MacOS
VMS
VOS
RiscOS
Amiga
MPEiX
#Assign the $home_directory variable the path of the user's home directory
my $home_directory = ($^O eq /Win/) ? $ENV{HOMEPATH} : $ENV{HOME};
#Then you can read/write to files in the home directory
open(FILE, ">$home_directory/my_tmp_file");
print FILE "This is a test\n";
close FILE;
#And/or read the contents of the file
open(FILE, "<$home_directory/my_tmp_file");
while (<FILE>){
print $_;
}
close FILE;