Impact of macOS Catalina Defaulting to Unix Shell using Zsh

Glad to!

How To Use Shebang At Top of Shell Script to Set Language

Normally, any line in a shell script that begins with a # is assumed to be a comment. The only exception to that is if it is the first line, and is #! followed by the program you want to use as an interpreter to the shell script.

Normally you will see something like this:

#!/bin/sh

#!/bin/bash

#!/usr/bin/perl

The reason to do this is that someone might be using a different shell but you want to make sure they use the right one, otherwise the script will fail.

BUT what if you installed a newer version of perl at /usr/local/bin/perl and want to use that one instead of the one at /usr/bin/perl?

Well, you could change all of your scripts to use #!/usr/local/bin/perl but then if you are on a Mac which does not have /usr/local/bin/perl installed, it will fail.

That is where env comes in.

By using #!/usr/bin/env FOO you are telling the script, “Use whichever version of FOO that you find first in the PATH."

So if your if PATH looks like this

PATH=/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin

then env will look at /usr/local/bin first, and then /usr/bin and so on. As soon as FOO is found in one of those folders, it will be used.

So, while I expect most of my zsh scripts will be used by people who only have /bin/zsh, because I use env I can use /usr/local/bin/zsh too.

(The only thing you have to be careful about is that if you use any features that have been added to /usr/local/bin/zsh but are not in /bin/zsh then you should specify /usr/local/bin/zsh.)

Portability Is Hard…

In an ironic twist, when I used to have a shell account on a Linux box, changing my zsh scripts to start with #!/usr/bin/env zsh failed because that version of Linux had env at /bin/env instead. Yet another reason I'm happy to have server be with Mac Stadium now.

“How do I tell which shell I’m using?”

If you have a shell script that works but you are not sure which shell is running it, add the line:

echo "$SHELL"

to the script and it will tell you, e.g. /bin/bash/ or /bin/zsh or whatever.

3 Likes