由于来自我们团队外部的压力,我们不得不将一百多个 Perl 脚本从 Sparc 移植到 x86。这意味着将数十条 shebang 行从其他内容更改#!/home/Perl/bin/perl -w
为其他内容,这真的很痛苦。什么是这样做的好方法(我在Lycos上找不到任何东西)?
还有,当我们被迫从 x86 迁移到其他东西(我想像 Cray)时会发生什么?有没有办法“面向未来”?
由于来自我们团队外部的压力,我们不得不将一百多个 Perl 脚本从 Sparc 移植到 x86。这意味着将数十条 shebang 行从其他内容更改#!/home/Perl/bin/perl -w
为其他内容,这真的很痛苦。什么是这样做的好方法(我在Lycos上找不到任何东西)?
还有,当我们被迫从 x86 迁移到其他东西(我想像 Cray)时会发生什么?有没有办法“面向未来”?
这是许多人提倡使用#!/usr/bin/env perl
而不是的原因之一#!/usr/bin/perl
:
Perl 是跨平台的。除非您的代码使用已XS
编译的代码或系统特定的路径、设施等,否则您应该没问题。
你有两个选择:
perl yourscript.pl
)。find . -name '*pl' | xargs sed 's/#!\/home\/Perl\/bin\/perl -w/#!\/usr\/bin\/env perl/
无论如何,shebang 行与您运行的硬件平台无关,而与您运行的 shell 无关。
集体改变shebang线并不是那么糟糕:
#! /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///
可能需要更聪明一点来处理开关,例如-T
必须在 shebang 线上的开关。
添加一个带有一些更改的试运行选项,以及一个有趣的用法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;
}
当然,另一种选择(可能更简单,尽管我会犹豫说“更好”)是软链接/home/Perl/bin/perl
到新系统上实际 Perl 二进制文件的任何位置......只有当您拥有高效的批量系统管理工具时才可行大多数正常的公司都应该这样做。