Howto Make Script More Portable With #!/usr/bin/env As a Shebang

by on March 6, 2007 · 16 comments· LAST UPDATED February 21, 2008

in , ,

You may have noticed that most shell and perl script starts with the following line:

It is called a shebang. It consists of a number sign and an exclamation point character (#!), followed by the full path to the interpreter such as /bin/bash. All scripts under UNIX and Linux execute using the interpreter specified on a first line.

However there is a small problem. BASH or Perl is not always in the same location (read as PATH) such as /bin/bash or /usr/bin/perl. If you want to make sure that script is portable across different UNIX like operating system you need to use /usr/bin/env command.

env command allows to run a program in a modified environment.

Find line

Replace with
#!/usr/bin/env bash

For example here is a small script:

#!/usr/bin/env bash
echo "$x and $y"


#!/usr/bin/env perl
use warnings;
print "Hello " x 5;
print "\\n";

Now you don’t have to search for a program via the PATH environment variable. This makes the script more portable. Also note that it is not foolproof method. Always make sure you have /usr/bin/env exists or use a softlink/symbolic link to point it to correct path. And yes your work (script) looks more professional with this hack :)

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 16 comments… read them below or add one }

1 bhaskar March 7, 2007 at 3:15 pm

I am confused.
Why is /usr/bin/env more portable than /bin/bash.
Besides on most linux distros bash is found in /bin, but env is not guaranteed to be found under /usr/bin.
e.g. in my case (FC5) env is under /bin.
My point is , which ever way you need to know the absolute path to either env, or bash, so why bother ?


2 nixCraft March 7, 2007 at 4:27 pm

If you move from Linux distro to BSD you will see bash is located at /usr/local/bin/bash OR to Solaris you will see bash at /opt or some other location. Instead of adjusting all the location admin can create a /usr/bin/env softlink and problem solved. Just imagine you have 100s of shell and perl scripts…

This is not just about Linux. It is about running a script under different UNIX like oses.


3 nag July 12, 2007 at 9:43 pm

Thanks for “shebang” and its explanation. Its really helpful.


4 IHar Filipau August 2, 2007 at 8:07 am

The only problem I have with env, that on some systems lacking ‘use warnings’, I can’t pass ‘-w’ on command line. Or is it possible somehow?


5 nixCraft September 6, 2007 at 9:44 am

You can pass /bin/path/to/mybinary -w


6 Carsten January 14, 2009 at 8:45 am

I do not feel very comfortable with the security aspects of this hack.
It may be more portable but it reduces control.
Bash and other shells are hardened so that they can be used for admin jobs withstanding tampering efforts by non root users.
Using the described “env” solution may introduce vulnerabilities which are difficult to oversee or analyze.
Instead of linking env and using it to deal with compatibity I rather add compatibility links to my systems which link bash or perl to a uniform location e.g. ln -s /usr/local/bin/bash /bin/bash


7 Terrible January 26, 2009 at 10:00 pm

Terrible advice. Do not do this. Portability should stem from your installion routines, not some security and design problem causing hack.


8 robsku December 17, 2010 at 11:29 pm

You could be correct, but I’d like to hear your opinion of why exactly is it more harmful?

Well, it runs the command, perl for example, like you would run perl by hand – so I assume it searches via PATH – I can see that individual user may then create executable ‘perl’ of his own under his home directory and change PATH so that env will call that… However that already means that user in question is doing this on purpose, in which case he could just call the harmful program himself – no need to even include the script, perl nor env on that and if done that way it would not affect other users which would still get to run the script as intended.

However security and holes in it can be complex issues and I’m not a professional at all… If indeed using env is more of a possible security issue than creating shebang pointing right to correct interpreter in install routine I would love to learn why exactly is it safer, about possible security issues in using env, etc.
I would think that when installed system wide both ways would be as safe – and one trying to do harm could install the whole software locally under his home directory anyway but could not alter what is ran when other users call the script in question – not understanding makes me even more curious, but most importantly I want to ensure security…


9 someone August 13, 2011 at 7:01 pm

Even the official python tutorial website is using:
#! /usr/bin/env python


10 Triston J. Taylor December 24, 2012 at 6:11 pm

Here’s an idea, instead of wasting cpu and peoples time, suggest a link to /bin/bash always. This stupid idea of using env command is a waste of the unix operating system.

Symbolic links were created to solve problems exactly like this. Some idiot came up with the great idea to make it more complicated by suggesting a link to bin env… I swear this is absolutely retarded.

Quit being lazy and put a proper link in /bin. What is the point in spawning processes you don’t need? More professional? According to who? The idiots who never wrote a single program of assembler code in their life? The idiots who couldn’t write a bash script to remove duplicate words from a list without resorting to external commands?

Oh yeah, you must mean those idiots…. The one’s who couldn’t code their way out of wet paper sack.


11 Triston J. Taylor December 24, 2012 at 6:16 pm

And another thing, if its really that important to be portable, and you can’t create a link in /bin then your scripts need to be auto-generated on-site with the proper header line.

Quit wasting resources and practice efficiency. Wastefulness is a bad habit that not only adds up, but is certain to be a perpetual mistake.


12 Anon March 21, 2014 at 12:24 am

Are you seriously saying that a person is an idiot just because of this? You look like one acting like you are the only one who knows… Just saying.


13 Ian Epp July 17, 2013 at 9:16 pm

@Triston J. Taylor
I came here to solve a problem with the python interpreter changing based on which python virtual environment was activated at a given time. Remapping the symlink doesn’t work at all as I may have one shell in one environment and another in a completely different one – it invokes different python symlinks. Using env fixes this perfectly.


14 Rodney September 20, 2013 at 7:50 pm

One problem with /usr/bin/env SomeCmd is you can’t pass additional arguments.

So you can’t /usr/bin/env SomeCmd -someArg -someOtherArg

Why? Because /usr/bin/env doesn’t support passing those as arguments on same platforms.

One hack to work around this is


15 Rodney September 20, 2013 at 7:52 pm
16 Ovidiu January 31, 2014 at 4:25 pm

It is not a portable solution. On Windows you could have C:\cygwin64\bin\env.exe instead of /usr/bin/env.

So assuming the path of env is not a portable solution.


Leave a Comment

Tagged as: , , , , , , , , , , , , , , , ,

Previous post:

Next post: