4

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

#!$SHELL

or

#!/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.

4
  • 1
    You could make another script with exec $SHELL "$@" or similar in it, then use that for the shbang.
    – Tom Hunt
    Nov 13, 2015 at 21:54
  • @TomHunt: Thanks! I was just reading about the old "exec hack". It looks like it's still handy!
    – kjo
    Nov 13, 2015 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, 2015 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, 2015 at 19:30

2 Answers 2

1
#!/bin/sh
my_script(){
    { cat; cat <&3; }>"$0"
} <<SHEBANG 3<<\SCRIPT
#!${SHELL}
SHEBANG
#now all the rest of your script

#goes in here

SCRIPT

my_script

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.

3
  • 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, 2015 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, 2015 at 23:26
  • Whoa, that's pretty cool!
    – kjo
    Nov 13, 2015 at 23:29
1

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.

#!/bin/sh

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

# Rest of script here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.