O zsh não é totalmente compatível com o bash. Há uma variedade de diferenças. O zsh mais recente é mais compatível com o bash (= ~ suportado, o exec agora tem as opções extras de sinalização, etc.), mas a compatibilidade total não é uma meta, nem mesmo em "emular".
Por exemplo, o bash substring é $ {foo: offset: len}, mas no zsh é $ foo [start, end] e esse é apenas um exemplo simples.
zsh é um shell influenciado pelo tcsh e pelo ksh, que faz muitas coisas à sua maneira; A compatibilidade do POSIX não é explicitamente uma meta, mas os desenvolvedores respondem aos patches que adicionam opções / emulam o comportamento que aproxima as coisas do POSIX. Mas quando você começa a realmente explorar o poder do shell, começa a criar scripts somente para gravação, mais ainda do que o bash.
O bash é POSIX sh + ksh + pedanticismo, com alguns recursos agora copiados do zsh. Ele também possui scripts somente de gravação, mas como possui operadores menos poderosos, você acaba não usando a concisão do zsh e as coisas podem ser mais legíveis (exceto por todas as citações para evitar a divisão do espaço em branco, o estúpido array $ do estilo ksh significa primeiro elemento da matriz, não todos os elementos da matriz, etc etc).
Escrever scripts que tiram o máximo proveito do poder de qualquer shell é imprudente, a menos que você esteja em um ambiente restrito (por exemplo, escrevendo scripts rc do sistema, onde alguns FSs podem não estar montados, etc.). Como ideal, use Perl / Python / Ruby / qualquer coisa grande o suficiente para que você não precise da expressividade do Bourne sh, se quiser que outros consigam mantê-la. Mantenha o material do shell para itens relacionados ao shell interativo (programação de conclusão de guias, etc).
Eu não usaria bash sobre zsh. Eu usaria o sh over zsh simples para scripts simples ou alternaria para uma linguagem em que matrizes associativas tenham operadores decentes (ao contrário do zsh, onde eles são novamente 'concisos'). Eu posso mudar um script sh para bash se precisar desse pequeno recurso para estender um script de trabalho comprovado existente e não tiver tempo para reescrevê-lo agora.