Perl脚本可移植性和未来打样

时间:2010-08-17 23:22:40

标签: perl scripting portability future-proof

由于来自我们小组外部的压力,我们必须将超过一百个Perl脚本从Sparc移植到x86。这意味着将数十条shebang线从#!/home/Perl/bin/perl -w改为其他东西,这真是一种痛苦。有什么好方法可以做到这一点(我在Lycos上找不到任何东西)?

当我们被迫从x86转移到其他东西时(比如Cray,我猜)会发生什么?有没有办法“面向未来”?

4 个答案:

答案 0 :(得分:11)

这是许多人提倡使用#!/usr/bin/env perl代替#!/usr/bin/perl的原因之一:

答案 1 :(得分:5)

Perl是跨平台的。除非您的代码使用XS已编译的代码或系统特定的路径,设施等,否则您应该没问题。

您有两种选择:

  1. 请勿使用shebang(perl yourscript.pl)。
  2. find . -name '*pl' | xargs sed 's/#!\/home\/Perl\/bin\/perl -w/#!\/usr\/bin\/env perl/
  3. 无论如何,shebang系列与您正在运行的硬件平台无关,而且所有这些都与您正在运行的shell有关。

答案 2 :(得分:4)

更改shebang行 en masse 并不是那么糟糕:

#! /usr/bin/perl

use warnings;
use strict;

use File::Find;

sub usage { "Usage: $0 dir ..\n" }

my @todo;
sub has_perl_shebang {
  return unless -f;
  open my $fh, "<", $_ or warn "$0: open $File::Find::name: $!", return;
  push @todo => $File::Find::name
    if (scalar(<$fh>) || "") =~ /\A#!.*\bperl/i;
}

die usage unless @ARGV;
find \&has_perl_shebang => @ARGV;

local($^I,@ARGV) = ("",@todo);
while (<>) {
  s[ ^ (\#!.*) $ ][#! /usr/bin/env perl]x
    if $. == 1;
  print;
}
continue {
  close ARGV if eof;
}

根据您所拥有的内容,s///可能需要更聪明一些,以处理必须位于shebang线上的-T等开关。

添加一个干运行选项,只需进行一些更改,再加上redo的有趣用法:

my $dryrun;
{
  die usage unless @ARGV;
  $dryrun = shift @ARGV, redo if $ARGV[0] eq "-n";
}

find \&has_perl_shebang => @ARGV;
if ($dryrun) {
  warn "$0: $_\n" for @todo;
  exit 1;
}

答案 3 :(得分:1)

另一种选择(可能更简单但我会犹豫说“更好”)当然是将/home/Perl/bin/perl软链接到新系统上的实际Perl二进制文件的位置......这是唯一可行的如果您拥有大多数普通公司应该使用的高效批量系统管理工具。