I'm looking for what to put on my_zsh_script.sh's "shebang line" that would have the same effect, portably, as

$SHELL my_zsh_script.sh

IOW, I looking for the valid equivalent of



#!/usr/bin/env $SHELL    

(In some systems, my value for $SHELL is a version of zsh that, under some circumstances, differs from what #!/usr/bin/env zsh resolves to.)

I suppose that I can always arrange to have my_zsh_script.sh custom-built, with the right shebang line hard-coded in, for each host I may want to run it on. I'm hoping to avoid this scenario.

  • 1
    You could make another script with exec $SHELL "$@" or similar in it, then use that for the shbang. – Tom Hunt Nov 13 '15 at 21:54
  • @TomHunt: Thanks! I was just reading about the old "exec hack". It looks like it's still handy! – kjo Nov 13 '15 at 21:55
  • If it's a zsh script, then it has to be executed with zsh, no? It's not portable if run by someone for whom $SHELL is, say, /bin/bash. – chepner Nov 21 '15 at 15:03
  • 1
    @chepner: correct. The only intended user of this script is myself, but over multiple Unix accounts. These accounts are very heterogeneous. It turns out that $SHELL is the most reliable way to get at the correct path to zsh over all these accounts. – kjo Nov 21 '15 at 19:30
    { cat; cat <&3; }>"$0"
#now all the rest of your script

#goes in here



most shells will put all of the contents of here-documents in secure temp files automatically. those that don't use pipes, and those buffers are usually more than enough to accomodate shell-script writes, but they're no sure thing, of course.

and functions are literal strings stored into the shell's memory. doing the above should only be required the one time, and afterwards your script will be interpreted by whatever was in $SHELL at the time you ran it.

  • 1
    So the script basically rewrites itself (>"$0")? Also, if I understand correctly, the first time around, the script needs to be called twice... – kjo Nov 13 '15 at 23:23
  • @kjo. basically. about being called twice... maybe. you pretty much can't do anything after the line on which you call the my_script() function, but, on the same line, you might my_script; exec "$0" - "$@". – mikeserv Nov 13 '15 at 23:26
  • Whoa, that's pretty cool! – kjo Nov 13 '15 at 23:29

The following checks if some special environment variable is set to some non-null value. If it is not, then the script reruns itself using $SHELL, but this time in an environment where the special variable is set. Once the special variable is set, the script then executes as intended.


if [ -z "$__run_with_zsh" ]; then
    __run_with_zsh=1 exec "$SHELL" "$0" "$@"

# Rest of script here

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.