In order to test some scripts1 in as many environments as possible, I've set up several VMs with UNIX (or Unix-like operating systems):

  • Linux
  • Solaris
  • OS X2
  • FreeBSD

I assume, though, that in many ways it's actually more important to test using different versions of each shell that I plan to care about, than to test using different operating systems.

Since I'd rather not have my VMs multiply in seemingly endless permutations, I'd like to install multiple versions of each shell on any given VM. For instance, if I test under [:bash,:zsh,:fish,:ksh,:csh,:tcsh,:sh,:dash,:ash] then I've got 9 shells, and if you assume I'm testing an average of 3 versions of each then I've got over 100 VMs:

# operating_systems * shells * shell_versions
            4       *   9    *     3

Is there any practical way to install and use multiple versions of a given shell on a single machine or virtual machine? Can I (e.g.) install Bash 1, Bash 2, Bash 3, and Bash 4 all on one Linux VM?

I realize that

  1. some combinations are less important and can probably be ignored, and
  2. ultimately I'd want to test multiple versions of each OS as well,

but those are really separate to this question, so I'm putting such issues aside to consider whether this is possible:

So: is there any practical way to install and use multiple versions of a given shell on a single machine?

1 I'm using the term "script" loosely. One of the first things I want to test is something that will be sourced by one's shell rc files, whether that be .zshrc, .bash_profile, or whatever, so it won't have its own shebang line. Hence the desire to make one bit of code work across multiple shells. Other things that would be useful across shells would be functions and aliases that I'd want to use on different machines although they won't necessarily all have my favorite shell (Z Shell) but might make me use Bash or Korn. Also any useful snippets that I might want to use in shell scripts on multiple machines, even when I can't put my favorite shell in the shebang line.

2 Totally tangential note, only included for the sake of not saying anything misleading: I haven't actually gotten the OS X VM set up, since this is quite a hassle, but I hope to, and included it in the list so no one would say "Hey! Why aren't you including OS X!?"

  • Do your shells need to be installed as /bin/sh, or will any pathname be OK? Nov 18, 2014 at 18:28
  • Can you set up different login environments with chroot? Nov 18, 2014 at 18:32
  • @MarkPlotnick: any path should be okay, as long as it's not horribly difficult to switch between them.
    – iconoclast
    Nov 18, 2014 at 18:39
  • @glennjackman: If you mean do I have access, then yes. I created these VMs so I have root access. But it's not immediately obvious to me just how I'd implement this.
    – iconoclast
    Nov 18, 2014 at 18:46
  • 1
    I meant chroot Nov 18, 2014 at 22:00

3 Answers 3


If you're happy to build from source, you can install each version into a separate prefix, then adjust the path in your scripts accordingly.

bash, fish, ksh, tcsh, zsh, and dash all support the --prefix argument to configure, so you can download each version, run ./configure --prefix=/opt/SHELL-VERSION; make; make install. Then to use each version, set PATH to have /opt/SHELL-VERSION/bin at the front.

csh is a bit different and will require more manual work; if you're sure you want it, you can extract the sources from the FreeBSD source tree and edit the Makefile, but most people actually use tcsh anyway.

I don't think there's a canonical source for ash but it will probably have a similar way of going about things.

  • I was just working on a function for csh and tcsh that would add export to it for compatibility with everything else, and discovered that they lack functions. Okay, csh and tcsh may be so prehistoric that it's completely worthless to try to support them. I never encounter them being used and haven't used either myself since about 15 years ago.
    – iconoclast
    Nov 19, 2014 at 4:14
  • tcsh is still maintained, and it's shipped as the default root shell on FreeBSD IIRC, so it might be worth testing against.
    – Zanchey
    Nov 19, 2014 at 4:20
  • Okay... they have parametric aliases, but the syntax is a %!#&$. I'm trying to get one working, in another question.
    – iconoclast
    Nov 19, 2014 at 4:48

As Zanchey said, you can install each shell version into its own prefix. If you want to put them in your PATH, you can rename them and copy them to /usr/bin/. For example:

$ bash1
bash-1.0$ ./myscript.sh
# Code here.
bash-1.0$ bash2
# And so on...
user@user-MacBook-Pro:~$ zsh1
# and again until you finish...
user@user-MacBook-Pro ~> exit
# Don't just skip into shells, or deal with the exit. Or just spam ^D.
$ exit

asdf is designed specifically to "manage multiple runtime versions with a single CLI tool" whether that runtime is a language or a shell or whatever. It has a plugin for Zsh, so this should be far more convenient than rolling your own solution.

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.