Beefy Boxes and Bandwidth Generously Provided by pair Networks RobOMonk
The stupid question is the question not asked
 
PerlMonks  

shebang line - foreign to me

by John M. Dlugosz (Monsignor)
on Dec 27, 2002 at 03:17 UTC ( #222457=perlquestion: print w/ replies, xml ) Need Help??
John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

Running under Windows, I have no need for a "shebang" line. Windows associates a file to its type via the file name's extension or a constant signature at some fixed offset in the file, and does not hard-code the location of the executable in the file. Until reciently the Mac has stored a file type as meta-data which is not in the file's text, so those users have to set the type themselves after downloading, anyway. VMS is totally different, and (according to perlrun) uses a couple lines at the top of the file that would not run on other systems (since it doesn't look like a Perl comment).

So, it looks like Unix systems are the only kind I can really address in regards to making my script friendly across systems. I can put a shebang (why isn't that shAbang, if it's short for sharp-bang?) line at the top of the script that I publish.

So the question is, what should it say? Different people install Perl in different places! Perlrun encourages two "standard" locations to be symlinks to the actual binary, and I suppose something like that is common on Unix systems. Is one better than the other? What do people really like to use these days? It also mentions the use of the env program which adds a level of indirection (sounds like a good idea) but mentions that not everyone has that.

So, what's the "best practice" for setting up the shebang line?

—John

Comment on shebang line - foreign to me
Download Code
Re: shebang line - foreign to me
by Willard B. Trophy (Hermit) on Dec 27, 2002 at 03:25 UTC
    I'm rather fond of:
    #!/usr/bin/env perl

    as I haven't met a recent Unix system that doesn't support it.

    I think it's also short for 'hash bang'.

    --
    $,="\n";foreach(split('',"\3\3\3c>\0>c\177cc\0~c~``\0cc\177cc")) {$a++;$_=unpack('B8',$_);tr,01,\40#,;$b[$a%6].=$_};print@b,"\n"

      Except:
      • On some systems (I forget which), it's #!/bin/env, not #!/usr/bin/env
      • I've seen recent systems that didn't have env at all.
      • It costs performance wise, with an extra fork to get to env before you get to the Perl binary.
      So, it's neither portable, efficient, nor necessary, except for sufficiently narrow values for each of those three.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        Performance wise, the difference between:

        #!/usr/bin/env /usr/bin/perl

        And:

        #!/usr/bin/perl

        Is almost nothing on a P3 800Mhz running Linux 2.4.20. Using Benchmark.pm and system("program.pl") the former runs at 3875.97 times per second and the latter runs at 3906.25 times per second. The env binary is only 11 Kbytes and should fit in RAM for any program executed frequently. The env binary also only runs exec(), it does not run fork(), so sensible systems (such as Linux) that do not need to reschedule a timeslice to complete exec() show almost no penalty at all (I suspect the slight penalty is due to the loading of the elf information and performing a dependency analysis of the shared libraries associated with /usr/bin/env).

        As I mentioned in my response, one of the reasons why /usr/bin/env would be necessary is the case where perl is network-mounted and a shell script is necessary to select the correct version of perl to execute for the host platform. In this case, the issue is that it would be impossible or impractical to do this sort of thing any other way.

        As for portability, env is located in /usr/bin/env on HP-UX, SunOS, Solaris, and Linux. If perl can easily have a symbolic link created at /usr/bin/perl, then env can easily have a symbolic link created at /usr/bin/env on whatever architecture you happen to be referring to that does not have /usr/bin/env.

Re: shebang line - foreign to me
by zengargoyle (Deacon) on Dec 27, 2002 at 05:05 UTC

    best practice would be to wrap up your script(s) in a module and patch them up when you install.

    or mabye just an install.pl script whose usage is mentioned in your README and/or INSTALL help.

    or possibly just mention that they may need to fix the line themselves. i can't say i've ever been really irate that somebody uses /usr/bin/perl even though i have to change it to something else.

      Exactly. This is why for all Perl scripts I'm going to distrubute on other systems I use ExtUtils::MakeMaker which does such patching automatically.

      It is very simple:

      < Makefile.PL file > use ExtUtils::MakeMaker; WriteMakefile(NAME => 'Hello', VERSION => '1.00', EXE_FILES => ['hello']); < MANIFEST file > Makefile.PL hello < hello file > #!perl use strict; use warnings; print "Hello, world!\n";
      Once finished you can type perl Makefile.PL; make dist and get tarball ready to install with tar zxvf Hello-1.00.tar.gz; cd Hello-1.00; perl Makefile.PL; make; make install

      Update: Replaced 'script.pl' with 'hello' in 'MANIFEST'.

      --
      Ilya Martynov, ilya@iponweb.net
      CTO IPonWEB (UK) Ltd
      Quality Perl Programming and Unix Support UK managed @ offshore prices - http://www.iponweb.net
      Personal website - http://martynov.org

        Exactly. This is why for all Perl scripts I'm going to distrubute on other systems I use ExtUtils::MakeMaker which does such patching automatically.
        Either that's a recent feature (and therefore not portable), or hasn't been documented.

        Where did you find out about this?

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: shebang line - foreign to me
by dws (Chancellor) on Dec 27, 2002 at 05:15 UTC
    So, it looks like Unix systems are the only kind I can really address in regards to making my script friendly across systems.

    Or Apache on Win32.

    Perl also picks up command-line args when it finds a shebang line at the top of a script. Check out "#! and quoting on non-Unix systems" in perlrun.

      And don't forget us, Cygwin users :)



      Just a tongue-tied, twisted, earth-bound misfit. -- Pink Floyd

Re: shebang line - foreign to me (Larry says...)
by tye (Cardinal) on Dec 27, 2002 at 07:43 UTC

    I'm with Larry on this one: #!/usr/bin/perl
    People who don't bother to put a symbolic link in /usr/bin when they install Perl deserve to have to edit the scripts that they download.

    (You likely have to move, rename, and chmod the script anyway. When I did lots of Unix stuff, I put shell scripts and Perl scripts in the src directory as this.SH and that.PL and had default install scripts that transformed this.SH into an executable "this" in the proper "bin" directory. The one for Perl scripts would have also fixed the #! line except that I always made sure I had a /usr/bin/perl symlink on all of my systems so I didn't have to.) (:

                    - tye

      The exception to this is that many products require a specific version of Perl. In this case, /usr/bin/perl is not enough.

      However -- since the people with these requirements should be dealing with the ensuing problems via another route, I too have chosen to use #!/usr/bin/perl in all scripts in our product as a matter of good form. #! is just not ever used at this point in time.

      The "#!/usr/bin/env perl" route (mentioned by somebody else) is another solution that is heavily used by installations that mount perl (or TCL, or ...) over the network, where the perl in the PATH is a /bin/sh script that automatically executes a platform-specific version of perl. Most UNIX installations do not allow "#!/path/to/executable" where /path/to/executable is a script itself. In many cases the #! line then takes the form "#!/usr/bin/env /network/path/to/perl/script". Note that UNIX operating systems also have different limits regarding the length of the #! line, sometimes as low as 31 characters in total.

Re: shebang line - foreign to me
by osama (Scribe) on Dec 27, 2002 at 09:57 UTC
    I always use #!/usr/bin/perl even when running only in windows.... most scripts I have ever seen point there, that works on all my Linux/AIX/Windows!! machines... these habits don't die.

    If a Unix user has perl somewhere else, I am sure they are used to changing it... or they'll just put a symbolic link there...

Re: shebang line - foreign to me
by Massyn (Hermit) on Dec 27, 2002 at 11:07 UTC

    If you're running CGI's on Windows, you'll need the shebang. But then it would point to something like #!c:/perl/bin/perl.exe. I found this when running Apache on Windows, not with IIS, as long as ISAPI is configured to execute .pl files through perl.

    #!/massyn.pl The more I learn, the more I realize I don't know. Albert Einstein 1879-1955

Re: shebang line - foreign to me
by gregor-e (Beadle) on Dec 27, 2002 at 16:13 UTC
    I'll add my voice to the chorus - #!/usr/bin/perl is best, even on windows systems since cygwin is a pretty common perl base under windows.

    As for shebang, the American Heritage Dictionary says:

    she·bang (shə-băng')
    n. Slang.
    A situation, organization, contrivance, or set of facts or things: organized and ran the whole shebang.

    (Origin unknown.)

    A one-size-fits-all word that pretty much covers the #! contrivance. Though they say "Origin unknown", I suspect it relates back to cannon, which make a slight "shh" sound as the touchhole is lit, followed in a few msec by "bang".

      Most every script I have ever recieved either had "/bin/perl" "/usr/bin/perl" or "/usr/local/perl" but I personally use "/usr/bin/perl" since that seems to be the most common usage. (Plus, that's what it says on all of the shirts at Thinkgeek.)

Re: shebang line - foreign to me
by Anonymous Monk on Dec 28, 2002 at 07:19 UTC
    I tend to use:
    #!/usr/bin/perl

    Even though I only have an Win box at the time, it doesn't hurt to be unix friendly.

    As for other scripts that have different setups. I have a search and replace script (in perl of course) that changes any script to my default. Not too useful for windows, but when I work on unix, or need to transplant my scripts to another system, it can help alot.
Re: shebang line - foreign to me
by toma (Vicar) on Dec 30, 2002 at 19:37 UTC
    I never use #!/usr/bin/perl as the perl for experimenting with new modules or executable scripts. This version of perl is used by various system scripts and is the responsibility of the system administrator. Changing modules used by #!/usr/bin/perl is very rude to an overloaded system administrator. Imagine trying to support perl sysadmin scripts on 2000 unix workstations, each with a different combinations and versions of modules that have been installed by end users! Also, some workstation vendors require that you not change this perl if you are buying certain types of support.

    Perl is a great sysadmin tool, so I don't want to make it more difficult to use in this role. Let the sysadmin change hundreds of machines at a time, and then if it breaks it will probably be obvious what went wrong :-).

    I always have at least one version of perl in my home directory, and my perl bin directory is ahead in the path of /usr/bin, so I always get my perl. Clever application writers use ExtUtils::MakeMaker as described above. This feature is clearly documented in the pod, and has been since at least 5.005_03.

    There is also the problem of the end-of-line break on the #!/usr/bin/perl line. If you really have #!/usr/bin/perl\r\n, the bash shell on linux will report  bad interpreter: No such file or directory. Since this problem for the unix user is in the whitespace, it is very hard to find. In that case, it is much better to have nothing at all on the shebang.

    So my preferences are to let ExtUtils::MakeMaker do its job, or don't use windows linebreaks, or have no shebang.

    It should work perfectly the first time! - toma

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://222457]
Approved by scain
Front-paged by andye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2014-04-19 16:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (483 votes), past polls