Perl 脚本可移植性和面向未来

发布于 2024-09-14 18:50:00 字数 334 浏览 7 评论 0 原文

由于来自团队外部的压力,我们必须将一百多个 Perl 脚本从 Sparc 移植到 x86。这意味着将数十行 shebang 行从 #!/home/Perl/bin/perl -w 更改为其他内容,这确实很痛苦。有什么好的方法可以做到这一点(我在 Lycos)?

另外,当我们被迫从 x86 迁移到其他东西(我想是 Cray)时会发生什么?有什么办法可以“面向未来”吗?

Due to pressure from outside our group, we have to port over one hundred Perl scripts from Sparc to x86. This means changing dozens of shebang lines from #!/home/Perl/bin/perl -w to something else, which is a real pain. What is good way to do this (I can't find anything on Lycos)?

Also what happens when we're forced to move from x86 to something else (like Cray, I suppose)? Is there some way to "future-proof"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

九局 2024-09-21 18:50:00

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

This is one reason many people advocate using #!/usr/bin/env perl instead of #!/usr/bin/perl:

诗笺 2024-09-21 18:50:00

更改 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/// 可能需要更智能一些才能处理诸如 < code>-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;
}

Changing the shebang lines en masse ain't so bad:

#! /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;
}

Depending on what you have, the s/// may need to be a little smarter to handle switches such as -T that must be on the shebang line.

Add a dry-run option with a few changes, plus an interesting use of 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;
}
简单爱 2024-09-21 18:50:00

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

您有两个选择:

  1. 不要使用 shebang 行 (perl yourscript.pl)。
  2. <代码>查找 . -名称 '*pl' | xargs sed 's/#!\/home\/Perl\/bin\/perl -w/#!\/usr\/bin\/env perl/

无论如何,shebang 行无关与您正在运行的硬件平台以及您正在运行的外壳有关。

Perl is cross-platform. Unless your code makes use of XS compiled code or system-specific paths, facilities, etc., you should be fine.

You have two options:

  1. Don't use shebang lines (perl yourscript.pl).
  2. find . -name '*pl' | xargs sed 's/#!\/home\/Perl\/bin\/perl -w/#!\/usr\/bin\/env perl/

In any case, the shebang line has nothing to do with the hardware platform you're running, and all with the shell you're running on.

杯别 2024-09-21 18:50:00

当然,另一种替代方案(可能更简单,但我会犹豫是否说“更好”)是将 /home/Perl/bin/perl 软链接到新系统上实际 Perl 二进制文件所在的位置。是...只有当您拥有大多数正常公司应该拥有的高效批量系统管理工具时,这才是可行的。

Another alternative (might be simpler though I would hesitate to say "better") is, of course, to soft-link /home/Perl/bin/perl to wherever actual Perl binary on the new systems will be... it's only feasible if you have efficient bulk system admin tools which most normal companies should.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文