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 the 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
zsh are in optional packages. On the BSDs, the preferred interactive shell is often
sh is based on either the Almquist shell 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.
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
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 an 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.