5

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"?

Ariel Bold
  • 245
  • 2
  • 8
  • @Ether - They do. IIRC the last owner was some Korean company. They have both HotBot aggregate search (their own+MSN+ask.com results) and the proprietary LyGO "visual search" engine - which sounds a bit cool BUT uses the same crappy way outdated old Lycos search index. – DVK Aug 18 '10 at 02:31

4 Answers4

11

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

Chas. Owens
  • 64,182
  • 22
  • 135
  • 226
  • How does this make my scripts portable? – Ariel Bold Aug 18 '10 at 04:27
  • They will run on whichever "perl" executable the system finds, via `/usr/bin/env`... – mfontani Aug 18 '10 at 06:02
  • @Ariel: More specifically, using `#!/usr/bin/env perl` will cause the program to be run using the first `perl` binary found in the controlling user's `PATH`. Note that if, by "x86" you mean "Windows", this isn't relevant anyhow, since Windows goes by the file extension and completely ignores the `#!` line. – Dave Sherohman Aug 18 '10 at 11:24
  • I use this script for Perl shebang headers: http://www.win.tue.nl/~rp/bin/envperl – reinierpost Aug 18 '10 at 17:00
5

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.

Pedro Silva
  • 4,672
  • 1
  • 19
  • 31
4

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;
}
Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
1

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.

DVK
  • 126,886
  • 32
  • 213
  • 327
  • What is "efficient bulk system admin tools"? I don't think we have that. – Ariel Bold Aug 18 '10 at 04:29
  • Something that'd allow you to create such a symlink on every single existing and new x86 server without doing it individually server-by-server (unless of course you only have 2-3 servers in which case it's feasible to do it by hand) – DVK Aug 18 '10 at 11:11