Search code examples
perlscriptingportabilityfuture-proof

Perl Script Portability and Future Proofing


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


Solution

  • 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;
    }