Can I assume that enough people have zsh installed to run scripts with a

#!/usr/bin/env zsh

as shebang?

Or will this make my scripts un-runnable on too many systems?

Clarification: I’m interested in programs/scripts an end user might want to run (like on Ubuntu, Debian, SUSE, Arch &c.)

  • 4
    Weird question. Who's your target? In certain circles (Ruby-on-Rails web developers) zsh may be popular while in others (banking sector) it's virtually unheard of. I think you should give a lot more info if you need proper advice on this one. – rahmu Mar 24 '13 at 17:00
  • General linux end user world. – Profpatsch Mar 24 '13 at 17:04
  • 2
    WRT "general linux end user world", zsh is non-standard. It is not installed by default (on most or all distros) or required by anything, so most people will not have it. – goldilocks Mar 24 '13 at 20:02
  • 3
    I don't have zsh installed on any of my systems, and I would not install it for a single script. You should even avoid bashisms even though bash is usually available. – frostschutz Mar 27 '13 at 21:04

For portability, no. While zsh can be compiled on any Unix or Unix-like and even Windows at least via Cygwin, and is packaged for most Open Source Unix-likes and several commercial ones, it is generally not included in the default install.

bash on the other end is installed on GNU systems (as bash is the shell of the GNU project) like the great majority of non-embedded Linux based systems and sometimes on non-GNU systems like Apple OS/X. In the commercial Unix side, the Korn shell (the AT&T variant, though more the ksh88 one) is the norm and both bash and zsh are in optional packages. On the BSDs, the preferred interactive shell is often tcsh while sh is based on either the Almquist shell or pdksh and bash or zsh need to be installed as optional packages as well.

zsh is installed by default on Apple OS/X. It even used to be the /bin/sh there. It can be found by default in a few Linux distributions like SysRescCD, Grml, Gobolinux and probably others, but I don't think any of the major ones.

Like for bash, there's the question of the installed version and as a consequence the features available. For instance, it's not uncommon to find systems with bash3 or zsh3. Also, there's no guarantee that the script that you write now for zsh5 will work with zsh6 though like for bash they do try to maintain backward compatibility.

For scripts, my view is: use the POSIX shell syntax as all Unices have at least one shell called sh (not necessarily in /bin) that is able to interpret that syntax. Then you don't have to worry so much about portability. And if that syntax is not enough for your need, then probably you need more than a shell.

Then, your options are:

  • Perl which is ubiquitous (though again you may have to limit yourself to the feature set of old versions, and can't make assumptions on the Perl modules installed by default)
  • Specify the interpreter and its version (python 2.6 or above, zsh 4 or above, bash 4.2 or above...), as a dependency for your script, either by building a package for every targeted system which specifies the dependency or by stipulating it in a README file shipped alongside your script or embedded as comments at the top of your script, or by adding a few lines in Bourne syntax at the beginning of your script that checks for the availability of the requested interpreter and bails out with an explicit error when it's not, like this script needs zsh 4.0 or above.
  • Ship the interpreter alongside your script (beware of licensing implications) which means you also need one package for every targeted OS. Some interpreters make it easier by providing a way to pack the script and its interpreter in a single executable.
  • Write it in a compiled language. Again, one package per targeted system.
  • "zsh-man" saying "no", I'm proud of you! ^^ Portability ftw! (with all its caveats...). +1. – Olivier Dulac Aug 29 '17 at 13:10

No, you cannot. What is guaranteed available is /bin/sh, essentially the original Bourne shell. Almost all (note the "almost"!) Linux installations will have bash, but on *BSD systems it is rare (the BSD persuation has severe misgivings about GPL code, like bash). I don't know what the standard shell is on Mac, but again, there are misgivings about GPL. Same for Solaris.

zsh is a niche shell, it isn't in the default install of Fedora (and I don't believe it is default for any major distributon).

  • 6
    Certainly not the original Bourne Shell, but rather a Posix shell on Posix compliant systems, which on many systems is /bin/sh, but not necessarily so (On Solaris <= version 10 this is /usr/xpg4/bin/sh) – Scrutinizer Mar 24 '13 at 17:52
  • Well, the “default” install doesn’t really matter. What matters is if it is installed at all. – Profpatsch Mar 24 '13 at 18:20
  • @Profpatsch, then the default install is very relevant (presumably the distribution determined what people really use). – vonbrand Mar 24 '13 at 18:34
  • 2
    @StephaneChazelas, "niche" as in "few users use it"/"few installations have it". It might be the best shell since sliced bread, but if only a small fraction uses it, you can't count that it will be installed everywhere. – vonbrand Mar 24 '13 at 21:14
  • 1
    Note that if you consider that the great majority of Linux deployments is embedded nowadays (think android, printers, routers, TVs, lightbulbs...), the great majority of Linux based systems does not have bash (though those systems are probably not the main target the OP had in mind for his question) – Stéphane Chazelas May 22 '15 at 6:03

I think it really depends on what zsh extra features you're using and where. If you're planning to distribute your script across the different users and systems I would suggest to use bash or even sh.

The same time if your script designed to be executed across your organization and you have convention to have zsh on your machines (for instance the same basic AMI) and your task have clear benefits from extensions like advanced file selectors or other stuff from http://www.rayninfo.co.uk/tips/zshtips.html I would say go ahead!


As stated, bash is commonly available in the default installation for many distros. Your script will not reach the greatest user base by relying on zsh.

An important question to answer before designing your script is "Why does it matter which shell a script is executed in?"

Different shells use different syntax or offer additional shell functions that may not be supported by other shells. To write a script for the "general linux end user world," determine whether your script uses any syntax or shell functions that rely on a particular shell environment.

For example, bash shell supports certain expansions that are not supported by dash, Bourne shell, or whatever /bin/sh points to on the user's system.

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Feb 19  2014 /bin/sh -> dash

Try executing echo {1..10} with /bin/sh compared to /bin/bash and you'll get very different output.

The same goes for zsh which, while supporting most bash syntax, offers additional expansion and syntax that is not supported by the bash shell. See this tables comparing shells for specific examples.

You could broaden your potential user base beyond bashby adhering to scripts that work when called with #!/bin/sh -u. However, this gives rise to another important question to ask: "What is being sacrificed in exchange for greater portability?"

Determine whether differences relating to security concerns, functionality, efficiency, or anything else you feel is a priority for your script would be worth the sacrifice. You may not want wide spread use of a script with a known security vulnerability just because it works in more environments.

So many scripts are written for bash that support for these scripts is used as a criteria when comparing command shells. Many more people will be able to run your script than if it relies on zsh or any other syntax exclusive to a shell environment.

Also, keep in mind that you don't ultimately have control over how the user executes the script (also useful for debugging scripts in different shells):

Remember that if you use a shell to read a shell script (“sh scriptname”), instead of executing it directly (“./scriptname”), the shell will treat all the comments at the start of the shell script as comments. In particular, the comment that specifies the interpreter to use when executing the script (“#!/bin/sh -u”) will be ignored, as will all of the options listed beside that interpreter.

So, the best you can do about this is make your scripts portable, so long as there is there is no great sacrifice to how it functions.

You might also see Bash coding conventions - Stack Overflow.

  • 1
    "What is being sacrificed"... look at autoconf. They targeted /bin/sh as in "Original Bourne Shell" because all shells support that (tiny) set of features. And they suffered for it greatly. – Jürgen A. Erhard Aug 30 '16 at 9:22

The only thing you can almost guarantee is that there is a /bin/sh. That might be an actually static linked shell, or it can be a link to another shell. That other shell usually detects that it is called as sh and will run in compatibility mode.

Notice the almost in the first sentence.

Every unix like system I ever worked on had it. Many of them also had bash installed (but not all of them. E.g. bash it is not installed by default on some BSD's. Some Linux distribution ship with DASH, the Debian Almquist shell instead.

What you can guarantee are your installation instructions. You can add a line to the README file stating that is needs zsh. If you build a package then you can mark zsh as a dependence. You can check for it with the autoconf/automake tools. You can check if zsh is found with in installation script (start with /bin/sh and try to locate zsh, if found continue. If not display an error. e.g. "Warning: ZSH is not installed. Please read the installation instruction file!".)

I am sure I forgot a few more options. But the key points are:

  • You can guarantee nothing until you checked for it.
  • You are almost guaranteed that /bin/sh is present, and that you can do some checking with that.
  • POSIX requires /bin/sh, AFAIU. Like it requires a few other reasonable utilities. Check the requisites the GNU autoconfiscation. – vonbrand Mar 25 '13 at 23:26
  • @vonbrand. POSIX doesn't require /bin/sh. It requires a sh which in the correct environment (which doesn't have to be the default environment) behaves as it specifies. /bin/sh may not be a POSIX shell. For instance on Solaris 10 and earlier, it still was a Bourne shell and the standard sh was in /usr/xpg4/bin. – Stéphane Chazelas Jul 31 '14 at 15:09

This is a good question. I have a library of tcsh scripts that have general use. However given the reputation of tcsh .. I need to rewrite them (otherwise they work fine). I think the answer is pretty simple: bash. It has the widest installed base due to GNU/Linux.

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.