Using env in shebang scripting language lines

Directly referencing your interpreter? Crazy…
Directly referencing your interpreter? Crazy…

I haven't written any geeky programming technical posts for a long time. Christmas Eve seems like just as good a time as any. Funny how Perl programming specifically always reminds me of Christmas because I got my first proper job after high school in 2004 writing Perl/MySQL code around Christmas time so I could buy people presents. Happiest time of my life then because I had purpose, direction and optimism.

This morning I'm talking about using env in the shebang line of scripting language source files (FreeBSD man reference). Quite frankly I'm surprised that as of 2008 the majoraty of files I download and look through still reference hard links to the interpreters such as the examples below:

#!/usr/bin/perl -w

The problem with hard/specific referencing is that you can't assume your system will have a filesystem configured in the same way as another. While us users of Unix-like systems are fortunate that our said systems have so much in common, there are still enough subtle differences between Unix-like OSs and even distributions of the same OS to cause problems.

For example, most GNU/Linux systems place all non system critical files in the /usr/bin directory. As a FreeBSD user I shivver in terror at the mere thought of this; on the BSDs we're even more specific and seperate non system critical files that come as part of the core system in /usr/bin, and files we later install ourselves in /usr/local/bin or /usr/local/pkg depending on our package manager. Much stricter, cleaner and easier to maintain… but that's for another post.

The solution to this is to call our scripting language using env which checks your system for the desired interpreter and executes. This means Linux users can share with BSD users can share with Mac OS X users etc without worrying about how said systems are configured. You can even pass regular options, very nice.

#!/usr/bin/env ruby -w

Using env to reference basic sh shell scripts would be overkill, but for languages such as bash, Ruby, Python, Perl etc it just makes sense. Sure you could just assume all your clients and servers will be GNU/Linux folk, and perhaps you'd be right… for now. I'm all for future proofing.