6

I was looking through my CPAN distributions and realized that I had various inconsistent things at the top of my .t scripts, based on where I'd cargo-culted them from. This of course offends me.

So, what's the "best" first line of a Perl test (.t) script? A non-scientific survey of my .cpanm sources showed me:

3429 use strict;
3211 #!/usr/bin/perl
1344 #!/usr/bin/env perl
 937 #!perl
 909 #!/usr/bin/perl -w
 801 #!perl -w
 596 
 539 #!perl -T

Related to What should I use for a Perl script's shebang line?, but here I'm wondering if the shebang is necessary/useful at all, if tests are always expected to be called from prove.

Community
  • 1
  • 1
Jonathan Swartz
  • 1,913
  • 2
  • 17
  • 28
  • 1
    Oleg - not sure why you're so offended by this question. Some .t files seem to have shebang lines of different kinds and some have none at all. Just wondering if there's a best practice or if it makes any difference. – Jonathan Swartz Jul 03 '12 at 18:55
  • I'm not offended. I have exactly two things to note on this: no difference from any other Perl script - covered in answer, and that shebangs are kludge of specific OS (not very convenient one in retrospect). Bottom point of my answer: don't worry about them - it is useless, or at least just treat them as any other script. – Oleg V. Volkov Jul 03 '12 at 18:59
  • 1
    It's too bad this was closed. There are factual differences between the general perl script and scripts running under prove. Specifically, if you want to run your test under tainting (I normally don't, even if it's a Good Idea), you need to have "#! perl -T" at least so perl will start up with tainting enabled. Theoretically, the -w flag should be useful to enable global warnings, but prove already adds that (that's a bug, IMO). Other flags as well could be useful. Unlike regular scripts, however, *no* first line is perfectly viable here, if you don't need any of that. – Tanktalus Jul 08 '12 at 21:08

2 Answers2

2

use strict; should be in EVERY Perl program (as well as use warnings; and probably a few others (depending who you talk to). It doesn't have to be the first line.

The rest of the stuff you present are merely multiple versions of the shebang. On Unix and Unix based systems, the shebang is used to tell the interpreter to use. If the shebang isn't there, the current shell will be used. (That is, if your shell supports the shebang1.).

If you are on a Windows system, that shebang line is useless. Windows uses the suffix of the file to figure out how to execute the file.

The question is whether you really even need a shebang line in scripts that you run through a test harness. I don't normally execute these test scripts individually, so there may not really be a need for the shebang at all. In the rare event you do want to execute one of these scripts, you could always run them as an argument to the perl command itself. The same is true with Perl modules.

So, why the shebang? Mainly habit. I put one too on my test scripts and on my modules. If nothing else, it makes it easy to run modules and test scripts independently for testing purposes. Plus, the shebang lets people know this is a Perl script and not a shell script or a Python script.

There's a little issue with the shebang though, and that has to do with portability. If I put #! /usr/bin/perl on my first line, and the Perl interpreter is in #! /usr/local/bin/perl, I'll get an error. Thus, many of the shebangs reflect the location of the Perl interpreter for that developer.

There's also another issue: I use Perlbrew which allows me to install multiple versions of Perl. The version of Perl I currently have in my shell is at /Users/David/perl5/perlbrew/perls/perl-5.18.0/bin/perl. That's not good if I pass that program to another user on another system. Or, if I decide I want to test my Perl script under 5.10.

The #! perl variant is an attempt to solve this. On SunOS (I believe), this would execute the Perl that's in your $PATH (since it could be /usr/local/bin/perl or /usr/share/bin/perl or /usr/bin/perl depending upon the system). However, this does not work on most Unix boxes. For example, on my Mac, I would get a bad interpreter error.

I use #! /usr/bin/env perl. The env program takes the argument perl, sees where perl is on my $PATH, and then executes the full path of wherever Perl happens to be on my $PATH. This is the most universal way to do the shebang and the way I recommend. It allows those of use to use Perlbrew without problem.

Note, I said almost universal, and not universal. On almost all systems, env is located in /usr/bin, but there apparently some systems out there where env is either on /bin, located elsewhere, or not on the system at all.

The -w turns on warnings when executing Perl. Before Perl 5.6, you used this to turn on warnings. After Perl 5.6, you can use the more flexible use warnings; and the -w is now considered deprecated2. Programs may use it because they were originally written pre 5.6, and never modified or the developer simply did it out of habit.

The -T has to do with taint mode. Taint mode is normally used for CGI scripting. Basically, in Taint mode, data from outside a program is considered tainted and cannot be used until untainted. Taint mode also affects @INC and PERLLIB.

The real answer is that there is no set answer. I'd put #! /usr/bin/env perl as my first line out of habit -- even if I never expect to execute that file from a Unix command line. There's no real need for it for these types of scripts that are almost always executed as part of the install and not directly from the command line. What you see is really the result of 30 years of Perl habits and cruft.


1. Your shell supports the shebang unless you're using a 30 year old version of the Bourne shell or a very old version of the C shell.

2. I actually don't know if -w has ever been officially deprecated, but there's no reason to use it.

David W.
  • 105,218
  • 39
  • 216
  • 337
-2

.t files are still regular Perl script. Use whatever you need for this particular script on first line.

Oleg V. Volkov
  • 21,719
  • 4
  • 44
  • 68
  • 2
    It is not only a matter of what I need if I want to publish on CPAN. The question is more of what most people would need and what is most portable I guess. – matthias krull Jul 03 '12 at 12:58
  • 1
    They're still **not a single bit different**, I don't understand why you need separate question. Besides, shebangs are just a Unix artifact. Just don't think about it at all. Whoever want to run tests will either use perl or prove. – Oleg V. Volkov Jul 03 '12 at 13:07