25

In scripts, first line should specify the path to interpreter.
But on different servers Linux, Unix, or BSD this path could be different.

What is more preferable?

#!/usr/bin/env bash 

or

#!/bin/bash 

3 Answers 3

25

If you want to use the system-installed version of a given interpreter that's installed in a standard location, use the direct path. If you want to use whatever version of the interpreter appears first in the user's $PATH, use #!/usr/bin/env ....

The env command invokes a specified command, letting you set or unset environment variables:

env FOO=BAR do-something
env DISPLAY=:0.0 xterm -ls &

If you don't specify any environment variables or other options, it will just invoke the named command. (Using it this way is arguably a bit of a hack.)

The purpose of writing the shebang as

#!/usr/bin/env interp

is to invoke whatever interp appears first in $PATH.

This means you don't have to know, when writing the script, exactly where interp is (say, if it could be in either /bin, /usr/bin, or /usr/local/bin). Of course you do have to know that env is /usr/bin/env, but that seems to be reasonably universal.

The advantage is that it invokes whichever version of the interpreter appears first in the user's $PATH. The disadvantage is that it invokes whichever version of the interpreter appears first in the user's $PATH.

For example, suppose I've installed a personal build of perl under my home directory, as $HOME/bin/perl, and I have $HOME/bin at the front of my $PATH. If I run a script whose shebang is

#!/usr/bin/env perl

then it's going to be run with my own installed perl executable -- which might not be a good thing. The author of the script probably hasn't tested it with the bleading-edge Perl that I built from source a month ago.

For something like Perl or Bash that's likely to be installed in a consistent location on most systems (/usr/bin/perl and /bin/bash, respectively), I'd use the direct path to the command. For something more obscure that could be installed differently on different systems, I'd either use the /usr/bin/env trick, or I'd write an installer that adjusts the shebang line as the script is being installed. (I used to have to do that for my Perl scripts.)

UPDATE : I've gone into a bit more detail in this answer to this question on the Unix & Linux site.

4
  • I've just started looking in to Ruby, and I found that the convention in Ruby is to start with [code]#!/usr/bin/env ruby[/code] for the sake of portability. Some noted that this makes it difficult to supply command-line arguments to the ruby interpreter, such as '-w', which would also be a problem for Perl.
    – bgvaughan
    Dec 16, 2011 at 21:31
  • @bgvaughan For Perl, it's traditional nowadays just to use #!/usr/bin/perl and then use use strict; use warnings; in the body of the script, rather than #!/usr/bin/perl -w. But -T has to be on the shebang. Dec 16, 2011 at 22:01
  • so why not use #!perl if we just want the first one on the path? Jan 5, 2018 at 14:50
  • @wheredidthatnamecomefrom: Because that doesn't work. The treatment of the #! line doesn't use $PATH. You have to specify the path of the interpreter. (I just realized that, at least on my system, it can be a relative path, but that's rarely useful.) Jan 5, 2018 at 16:54
6

The best practice is this:

#!/usr/bin/env bash 
#!/usr/bin/env sh
#!/usr/bin/env python

And so on...

When Ubuntu first started using dash, some scripts broke. There was discussion about it. Most scripts were written #!/bin/sh which was a link to /bin/bash. The consensus is this: the script writer is responsible for specifying the interpreter. Therefore, if your script should always be invoked with BASH, specify it from the environment. This saves you having to guess the path, which is different on various Unix/Linux systems. In addition, it will work if tomorrow /bin/sh becomes a link to some other shell like /bin/wthsh or some other nonsence.

1
  • The obvious alternative fix for the dash problem was to write #!/bin/bash. I agree that the script writer is responsible for specifying the interpreter, but all that means is if you need bash, say bash not sh Aug 11, 2017 at 7:10
1

FYI it is a shee-bang #!, you need the #. You use this line to identify what interpreter to run the script with.

By default, Ubuntu links /bin/sh to dash

Depending on how much you might like to know about dash and why dash is used for system or deamon shells see:

cyberciti.biz dash

Ubuntu dash man page

Bash is the default shell used by most Linux users, and has different features then dash. A script written for bash may or may not run properly if run with dash, the more complex the script the less likely it will run.

Script written for perl, python, etc. will not run at all with /bin/sh or /bin/bash.

So when you write a script, you identify what interpreter should be used with the shee-bang

The selection of what to use is made by the author of the script, and one is not better then another, they all have various features, advantages, and disadvantages.

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .