0

I am writing a script which might be sourced either by bash or zsh. Depending on the shell, my script might do things differently. Currently I have:

if [[ -n $BASH_VERSION ]]
then
    # Do the bash-specific stuff
elif [[ -n $ZSH_VERSION ]]
then
    # Do the zsh-specific stuff
fi

Question: Is there a different/better way to detect which shell is sourcing my script? I know about the $SHELL variable, but that is the default shell, not the shell that is sourcing my script.

Hai Vu
  • 37,849
  • 11
  • 66
  • 93
  • 1
    I would recommend against trying to write a dual-shell script. Keep in mind that the entire `if` statement must parse successfully, regardless of which branch will be taken, so there can be cases where you can't simply "hide" `zsh`-only syntax from `bash`. – chepner Jul 01 '20 at 03:22
  • @chepner, I appreciate your input, but don't want to maintain two separate scripts because most of the code is the same for both shells. – Hai Vu Jul 01 '20 at 04:28
  • Can you abstract the differing code into a file to source? – chepner Jul 01 '20 at 11:50
  • @HaiVu : I think your approach is kind of OK, at least if you have control of the environment. Of course, a (malevolent) user of some non-bash shell might legally set the variable `BASH_VERSION` before sourcing your, and trick your script into believing that it is executed by bash. – user1934428 Jul 01 '20 at 13:39
  • @chepner Your approach is probably what I will adopt: common code in one file, and depending on the shell, the common code will source different file. Thank you. – Hai Vu Jul 01 '20 at 18:49

1 Answers1

3

No, there is no fundamentally better way.

However, you may wish to use POSIX compliant comparisons and eval any code that isn't valid POSIX:

if [ -n "$BASH_VERSION" ]
then
  eval 'declare -A foo=([shell]=bash)' 
elif [ -n "$ZSH_VERSION" ]
then
  eval 'declare -A foo=([shell]=zsh)'
elif [ -n "$KSH_VERSION" ]
  eval 'declare -A foo=([shell]=ksh)'
else
  foo_shell="sh"
fi

This allows the script to work correctly under shells like dash which doesn't understand [[ .. ]], and where array syntax would cause parsing errors.

that other guy
  • 116,971
  • 11
  • 170
  • 194