Most advice for Mac is written assuming you use the Bash shell. If I switch to zsh, how incompatible do I become with current Bash scripts that I have on my system, and advice people on SU give me?

Does the #!/bin/sh line at the beginning of my scripts help?

Edit: Irrelevant to the question is why I want to do this. Better tab-completion. I just tried out zsh putting in a login script as suggested here and I'm absolutely blown away.

  • And, now, MacOS Catalina brings us zsh as the default, instead of bash. Hoping this question and its answers are still mostly relevant 9 1/2 years later, lol! – leanne Nov 19 '19 at 20:37

The shebang line you show means to run the script using the Bourne shell (or another shell in compatibility mode). Those scripts will likely continue to run using the same shell they are now if you switch to zsh as your interactive shell. The only way that will change is if you link sh to zsh, but that shouldn't change the functionality.

You will find a certain amount of compatibility between zsh and Bash when used as your login shell or when writing scripts specifically calling for one or the other using shebang lines like:




However, there are a lot of things that zsh does differently or that Bash can't do at all. Bash is much more widely used, so there are fewer people familiar with the intricacies of zsh. Information on it is widely available, though. Also, you'll find that there's more than adequate help available here.

You'll find that for writing scripts either shell is considerably more powerful than the Bourne shell (sh), but at the expense of portability. Also, since Bash is more widely used than zsh, its scripts are relatively more portable.

  • Thanks for that. You say "either shell is considerably more powerful than the Bourne shell." You mean bash or zsh as you show in the shebang line? – Dan Rosenstark May 17 '10 at 10:48
  • @Yar: Yes, both Bash and zsh (and even the Korn shell, especially ksh93) have more capabilities than sh. – Paused until further notice. May 17 '10 at 10:54
  • Okay, so almost all shell scripts are written for compatibility mode. I had no idea. Meanwhile my shebang line says #!/usr/bin/env ruby most of the time, but I do use a lot of other people's sh scripts. – Dan Rosenstark May 17 '10 at 11:32

I'm not a zsh user, but from what I've read on SuperUser and other places, I've always gotten the impression that its fans focus on its extra features for interactive use more than for scripting. The first sentence of the description of zsh on the ZSH site, echoes this emphasis on the interactive features: "Zsh is a shell designed for interactive use, although it is also a powerful scripting language."

That said, if you're planning switch your login shell, you can continue to write your scripts in bash. As another answer pointed out, bash scripts will be more portable.

Existing scripts with the explicit #!/bin/sh (or #!/bin/bash or any other path) will continue to work fine regardless of your login shell.

  • When I write scripts on my own, I use Ruby :) good answer, thanks! – Dan Rosenstark May 17 '10 at 10:49
  • using zsh is incredibly convenient. Scripting it, not at all. btw, zsh acts differently depending on how you call it, ie if /bin/sh is a symlink to /bin/zsh, then zsh will act more like /bin/sh – chiggsy Dec 12 '10 at 3:16

Here you will find a list of "bashisms", i.e. pieces of code that will run in the bash shell but not in other bourne compatible shells.

If you want to achieve maximum portability when writing shell scripts than start your script with #!/bin/sh and avoid "bashisms", so that it will run in any other posix compatible shell, like ksh or zsh.

  • Thanks, good information when added to the other answers. – Dan Rosenstark May 17 '10 at 10:50

/bin/sh points to bash, running it in compatibility mode. The only thing changing your login shell changes is which built-ins are available, and how they work. Scripts follow their shebang line.

  • 2
    It should be noted that this is true on some systems. On others, it's linked to dash or ash or others or it's even actually the real deal Bourne shell itself. – Paused until further notice. May 17 '10 at 10:56
  • Yup. But the question is tagged "osx". – Ignacio Vazquez-Abrams May 17 '10 at 11:16
  • 1
    Unfortunately, "noted" is too small to be a comment on SU. – Dan Rosenstark May 17 '10 at 11:50

By “switch to zsh”, I assume that you mean one of two things:

  • you will use chsh (or equivalent) to change your login shell to zsh, or
  • you will configure Terminal (or equivalent) to use zsh as its default shell.

Most shell programs (shell “scripts”) will include a “shebang”/“hash-bang” line. The shebang declares which interpreter (shell) should interpret (run) the program that follows it.

As several other answers indicate, shell programs that use a shebang line will not be affected by the user's selection of login shell, nor by the interactive shell that is the parent or Nth-parent of a launched shell program.

If you are installing a new version of zsh and including it in your PATH, programs that use a shebang like #!/usr/bin/env zsh will use that new version (when the are started with a PATH that puts the new zsh first). This can only cause problems if some incompatible change was made between your old/original version of zsh and the new one. Note that this would be an intra-zsh (inter-zsh-version) problem, not the inter-shell problem about which I suspect you are concerned. This is usually a much smaller category of error than if (e.g.) you tried running a ran a bash program with ksh.

Not using a shebang line is inherently not portable between user environments. The result of trying to run an executable, non-binary file that lacks a shebang depends on the environment (OS, shell, possibly login shell, and environment variables). When such a file is run on my Mac OS X 10.4 system, the behavior varies according to the shell that runs it. ksh, and bash both interpret the file in a forked copy of themselves. zsh always passes it off to /bin/sh. If some program were to try to exec it directly, it would fail with ENOEXEC (this happens inside the shell, they just “cover for it” by “running” it in an alternate way). I have a vague memory of some ancient systems even trying to use the user's login shell in this situation, but my quick searching did not turn up anything useful.

A non-binary file is a file that the kernel does not recognize as one of its supported binary object formats.

As far as interactive compatibility goes, zsh supports much of the extended syntax from bash and ksh (some of if must be enabled with shell options, though), so much of the “shell” advice you find on Super User will work just fine in zsh (even if some of it is comprised of “bashisms”). Some things (command line editing bindings, completion, prompt displays, etc.) are wholly different from bash and ksh and will require different syntax for similar operations.

zsh does have a bit of bash completion compatibility, but I have never tried it.

  • Still processing this. +1 for now :) – Dan Rosenstark May 17 '10 at 10:50
  • 1
    It works better ( zsh's bash completer ) than bash. – chiggsy Dec 12 '10 at 3:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.