Impact of macOS Catalina Defaulting to Unix Shell using Zsh

I kinda ignored the word "zsh" above when I saw it, but you made me want to google it. And my reaction was "Wow!"

You say it's the default in Catalina, and I heard that Catalina my arrive in a week. I didn't even know it was available in Mojave. But I just typed "zsh" and it seems to be available now.

I'm not an elite wizard with shells, but I tend to use them a lot, even in situations where KM can do the same things. So any upgrade to the default shell is like an upgrade to KM to me.

I'm inferring that the KM "Execute Shell script" action will default to zsh when Catalina arrives. True or false?

I doubt it. That might break many (all?) existing KM Shell Scripts.
IAC, KM doesn't even use the same today as Terminal.

We'll need @peternlewis to jump in and clarify expectations for running KM under macOS Catalina.

Do these scripts have a shebang which tells the OS which shell to use?

If so, you might be fine...

Also, it looks like existing user accounts will keep bash for now:

Yes, but any new accounts or any accounts on new Macs seem to be impacted. So this will have an impact of KM users if it's true.

A agree with JM that this is a concern, but I doubt that most or all scripts, as he opines, will be broken. In fact I couldn't get a single command to break in any of my tests. I don't think zsh was intended to break anything.

I've never used a shebang when I write a script for the Execute Script action. That's why I asked about the default. The default is when you don't specify any shell.

Yes, zsh is installed by default at least as far back as 10.11 (El Capitan), and possibly further, I just don't have any older Macs to check.

1 Like

I think zsh is the default for new user accounts in Catalina but existing user accounts that were migrated from a previous version will not default to it. They will stay with bash. As a result existing users are not converted to zsh.

That’s a relief.

I’m not a heavy user of shell scripts. But I wouldn’t want to have to rewrite the few I have, alongside all the other Catalina breakage.

You may not have to rewrite anything if the KM Execute Shell script action continues to use bash instead of zsh. That's why I wrote the top post in this thread, to find out which shell would be the one used by the KM action.

On the other hand, if you should ever create a new user account on your Mac, then that could cause your macros to fail on that new account. It's complicated, so that's why JM asked Peter above for more information.

IMO, you should:

  1. Always define which shell you want to use with a "shebang" such as #!/usr/bin/env zsh -f.

  2. Anticipate a day in which bash is no longer installed at /bin/bash (or at all) and use #!/usr/bin/env bash as the shebang if you have a bash-specific script. That way if you add bash via Homebrew and it ends up at /usr/local/bin/bash then your bash script can still work.

  3. Migrate to zsh whenever possible because it will continue to be installed by default even if bash is not.

3 Likes

I really like this! Thanks for sharing.

For those of us who don't speak "shell", would you mind explaining this shebang command?

Thanks.

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

Thank you! That is very helpful! :+1:

And if it isn't obvious, "shebang" is most likely a slang variation of "hashbang" where "hash" is a term sometimes used for "#" and "bang" is a short form for "exclamation mark".

#!

Some people say the "sh" in "shebang" comes from "sharp" which is a musical term for "#" and some say it comes from the shortcut for the standard shell "/bin/sh" but I don't believe either of those theories.

Or, alternatively, don't execute a shell script using the Execute Shell Script action, instead pass your command to an Execute Macro action and within that macro's code you can insert the shell of your choice.

Now that will work if your command is a single line long, which many are. But the parameter text field of Execute Macro doesn't let you insert multiple lines at one time unless you use the %Return% token inside the text field. Or alternatively you can pass the parameter to the Execute Shell Script action using a variable name, and use AppleScript to dereference the variable. That's a more robust way to pass multiple line arguments as a parameter.

I'm a strong believer in creating macros for standard actions for a variety of reasons. Typically because the built-in actions contain assumptions that I want to redefine. In fact I have a library of them which someday I plan to post on this site.

As far as I understand it, upgrading to Catalina will not change your shell (by default, currently bash), only creating a new account (or installing Catalina fresh and not migrating) would result in using zsh.

Catalina is only changing the default shell, not your current shell.

Ironically, I used to use zsh decades ago, but eventually got tired of having to install it everywhere and gave up and used bash, and only in the last couple years have I actually fully committed to bash. Timing, right?!

Whether switching the zsh is an “upgrade” or not is an open question - it is different, but not necessarily better.

In any event, this wont affect the Execute a Shell Script action since it uses /bin/sh to execute the script, which you may start with #! to explicitly specify what shell or language to run, but that is all handled by sh.

So if you want to write your scripts for zsh, just start them with #!/bin/zsh, which should work for any recent version of OS X.

2 Likes

It is unlikely /bin/sh will ever not be installed, since it is typically used to process the script that reads the #! line. On OS X, sh is basically just bash (though not a symlink or hardlink interestingly enough). On Ubuntu it is a variant of dash, and much smaller.

Thanks. That is the answer to my original question, which was "will the Execute Shell script action default to zsh?" And now we see it won't, even for new accounts or new computers.

Since future accounts/users of macOS will be defaulting to zsh, and since the KM Execute Shell Script action will not be defaulting to zsh, perhaps the wiki needs to state that the KM Execute Shell Script action uses a specific shell different from the default macOS shell. The current wiki does allude to bash quite a few times but doesn't actually say the action uses bash. Otherwise a reasonable person will think that it's using the macOS default shell. Alternative the action could be renamed "Execute Bash Shell Script" if the documentation isn't updated.

The action is called Execute a Shell Script - it executes a Shell (sh) script. For the most part, if you want to do anything more than a trivial command, you should specific what language you want to execute in with the #!.

1 Like