Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

shebang anomaly

by perlboy_emeritus (Sexton)
on Apr 18, 2018 at 21:09 UTC ( #1213140=perlquestion: print w/replies, xml ) Need Help??

perlboy_emeritus has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I run Perl natively in macOS (v5.18.2) and in perlbrew (v5.20.3) and in debian in a VirtualBox vm (v5.24.1). The Perl code is common by design, meant to be portable and shared by all of these separate Perl environments, so my shebang line is:

#!/usr/bin/env perl -w or #!/usr/bin/env perl -wd

depending on whether I wish to debug. This shebang works correctly in macOS, either the native perl or the perlbrew perl but in debian env does not like either the -w or the -wd arguments. This, despite the (relatively) common man pages for env that assert that the command handed to env can take arguments, as in:


env [-iv] [-P altpath] [-S string] [-u name] [name=value ...] [utility [argument ...]]


env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]

When I run perl scripts shared from macOS in debian I have to remove -w or -wd, otherwise I get:

/usr/bin/env: 'perl -w': No such file or directory

The single quotes in that error message are from bash, not my script. I have tried to quote -w and -wd but explicitly quoting those arguments does not change the outcome. The bash shell or env or whatever are treating -w and -wd as the names of files and failing to find either, barf that error message. It is important that I be able to share Perl scripts between all of these execution environments so the shebang must be the same in all. What is debian env doing that the native macOS env is not? Is this possibly a bug in GNU env (v8.26)?

I suppose, technically, this is not a Perl question, so perhaps I should post this to stack overflow or some other technical site, but I thought I'd try Monks first.

Replies are listed 'Best First'.
Re: shebang anomaly
by choroba (Archbishop) on Apr 18, 2018 at 21:16 UTC
    Yes, shebang line is split into the interpreter and parameter, not parameters. See Silly things to do with shebang lines for some hints how to workaround the limitation.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Thanks choroba, but I don't think that article is on point for my problem. Let me state it again but more precisely. Every one of my Perl scripts has these two opening lines:
      #!/usr/bin/env perl -w ##!/usr/bin/env perl -wd

      I switch between these two lines, the first for ordinary runs, the second for debug runs. When I wish to debug I invert the lines, comment out the second, uncomment the first and proceed. Both these shebang lines fail in debian but work correctly in macOS. In debian I cannot have any argument to perl from an /usr/bin/env shebang despite rtfm. That page says the command can take an argument. True, if the argument was an argument list I would certainly quote it so that it appears as a single argument. In both of those example shebangs, I cannot have any arguments no matter how I quote them, and I've tried every quote option there is.

        The shebang line has never been specified as part of POSIX, SUS, LSB or any other specification. AFAIK, it hasn't even been properly documented.
        There is a rough consensus about what it does: take everything between the ! and the \n and exec it. The assumption is that everything between the ! and the \n is a full absolute path to the interpreter. There is no consensus about what happens if it contains whitespace.

        1 Some operating systems simply treat the entire thing as the path. After all, in most operating systems, whitespace or dashes are legal in a path.
        2 Some operating systems split at whitespace and treat the first part as the path to the interpreter and the rest as individual arguments.
        3 Some operating systems split at the first whitespace and treat the front part as the path to the interpeter and the rest as a single argument (which is what you are seeing).
        4 Some even don't support shebang lines at all.

        Thankfully, 1. and 4. seem to have died out, but 3. is pretty widespread, so you simply cannot rely on being able to pass more than one argument.

        I don't know if you ever gathered this from the other replies, but from choroba's "interpreter and parameter" and your "in both of those example shebangs, I cannot have any arguments" shows that, at least originally, you didn't understand. In the shebangs

        #!/usr/bin/env perl -w ##!/usr/bin/env perl -wd
        The "/usr/bin/env" is the interpreter, and "perl -w" or "perl -wd" is the single parameter (argument). Because it's one entity, then some versions of env will try to run "perl -w", and doesn't find anything to run that's P E R L SPACE DASH W as the name. (the same as you might get on other systems if you tried /usr/bin/env 'perl -w' or /usr/bin/env 'perl\ -w'.)

        Apart from all the examples given, there is a script in that page called "cmd" which allegedly will solve your problem by using: #!cmd /usr/bin/env perl -w. However, unless I am doing something wrong, it does not work for me. Although it should because what it does is straight-forward: breaks the command line and spawns yet another perl process with these args and your actual perl script.

        Maybe you will have better luck than me if you were to try having two shell scripts and calling perl differently?

Re: shebang anomaly
by kcott (Bishop) on Apr 19, 2018 at 11:26 UTC

    G'day perlboy_emeritus,

    I encountered the same issue recently where the shebang I'd been using for years on macOS (and Mac OS X previously) failed unexpectedly on Linux.

    See my post (from about 3 weeks ago): "shebang problem on openSUSE". There's excellent responses and external links which should explain all.

    — Ken

      G'day yourself Ken,

      I stole a fantastic Aussie plum when I married in Sydney one of your country-persons. That cmd code that choroba cited is a simple Perl script. I downloaded it to macOS and tested. It works as advertised, except it is not a native env. If you want to print the environment you must say:

      cmd env

      Mine will emulate env and replace GNU env, because I run multiple Perl's in multiple locations in the file system, and the scripts must not be aware of this. Next I'll try it in debian, but looking at the code, I can't imagine it not working. I may still implement it in C, just for grins. It should work for you too. Best...

Re: shebang anomaly
by learnedbyerror (Monk) on Apr 22, 2018 at 21:27 UTC

    I feel your pain with the changes that Apple has brought about as part of High Sierra.

    Almost like you, I routinely use the #!/usr/bin/env perl in my perl code. I differ in that I almost never use the command line switch(es) on it since the warnings pragma was introduced with perl 5.6. I recognize that the scoping behavior is different between the two and will occasionally use the -w when testing new modules that I haven't used before to see if something amiss may exist. And, I pretty much always type perl -d ... when I want the debugger or more often just hit the up arrow key to recall the command from my history.

    Maybe this approach will be useful to you.

    Also, while I am not a heavy user of PDL, I did recently install PDL and PDL::Graphics::Gnuplot in a perlbrewed perl 5.22.3 and don't remember having any problems installing it. I was setting up a new perl 5.26.2 this weekend when I saw your post. I went ahead and installed both on it. PDL installed and passed all test. PDL::Graphics::Gnuplot failed one test out 185.

    # Failed test 'Setting empty plot title sets an empty title' # at t/plot.t line 862.

    I am running 10.13.4. I also am an avid user of Homebrew and my success may be that I have packages installed from it that are used instead of the native packages from Apple. As a general rule, I do not use the Apple perl and only use Xcode for Apple specific work.

    Cheers, lbe

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2020-12-01 12:32 GMT
Find Nodes?
    Voting Booth?
    How often do you use taint mode?

    Results (6 votes). Check out past polls.