#!/usr/bin/env Interpreter Arguments -- portable scripts with arguments for the interpreter

Here's an inline solution to work around the portability problem for ZSH.

#! /bin/sh

if [ -z "$IN_ZSH" ]; then
  export IN_ZSH=1
  exec zsh -f "$0" "$@"
fi

## Your ZSH script here

Some other methods to try include

  • Passing env variables via /usr/bin/env which modify the behavior the same as --options such as doing
    #! /usr/bin/env POSIXLY_CORRECT=1 bash
  • Using clever commenting tricks, such as how this script starts out using SH but invokes TCL on the same script
    #! /bin/sh
    # \
    TCLBIN=/usr/bin/tclsh; \
    exec $TCLBIN "$0" "$@"
    # Execute the rest via tclsh
    set argc
  • Setting the option once in the interpreter, if the --options being passed in do not affect the load behavior
    #! /usr/bin/env bash
    # Exit if any error detected
    set -e
  • For perl, if you're able to use newer versions, this may work in lieu of -w:
    #! /usr/bin/env perl
    use warnings;
  • Using a bootstrap invoke.sh script instead of /usr/bin/env to use your PATH, calling with /path/to/invoke.sh script with your script starting with #! zsh -f
    #! /bin/sh

    SCRIPT=$1
    shift 1
    cmd=`sed -n -e 's:#! \?::' -e '1p' $SCRIPT`
    exec $cmd $SCRIPT