Take the 2-minute tour ×

I've a simple script:

#!/usr/bin/env perl -w
print "Hello World\n"

Make this executable, run on Linux, and I get:

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

(without the -w, this works OK)

Running the same script on a Solaris 8 machine produces the correct output.

Any suggestions as to why this is ?

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

It's not env; it's the kernel's #! handler. Everything after the first word (/usr/bin/env) is passed as a single argument string. Safest/most portable is to not put anything after the perl there.

share|improve this answer
add comment

The wikipedia article mentions this portability issues:


"Another portability problem is the interpretation of the command arguments. Some systems [12] do not split up the arguments; for example, when running the script with the first line like,..."

I found this a bit surprising, but it is the shell that does the parsing of arguments on spaces, and there isn't a shell involved here.

share|improve this answer
Not just the shell. #! scripts are handled by the kernel directly (#! is actually defined as an executable "magic number"), and the kernel parses the #! line and spawns the named program, passing the rest of the line as parameters. On most commercial Unixes, the line length is limited to 40 characters and the entire line after the space following the executable name (if any) is passed as a single parameter. Linux and *BSD kernels do more complete line parsing and the length limit is something like a memory block (4KB). –  geekosaur Mar 17 '11 at 0:16
One of the easier sources to find of documentation for this is the perlrun(1) manpage, where it talks about #! emulation and its pitfalls. –  geekosaur Mar 17 '11 at 0:18
add comment

Which shell are you using on both machines? Also, which version of Solaris and Linux are you using?

It's possible that you're using KSH on Solaris by default and BASH on Linux. This difference may affect how the shebang line is executed.


Tom Purl

share|improve this answer
using bash on both Solaris and Linux, also tried (t)csh; haven't tried kornshell. –  Tim T. Mar 15 '11 at 17:53
#! isn't handled by the shell, but by the kernel. –  geekosaur Mar 15 '11 at 17:54
checking with strace: I see execve("/usr/local/sbin/perl -w",["perl -w", "./testperl"]) falling back to /usr/local/bin, /usr/sbin etc. –  Tim T. Mar 15 '11 at 18:02
Thanks for correct me guys. This is great information. –  Tom Purl Mar 16 '11 at 12:44
add comment

Your Answer


