Get script name in bash and zshn bash and zsh

problem

Here's an edge case I faced recently:

We all (should) know that you shouldn't source a bash script in an interactive shell session using another shell... But sometimes it happens... 😇

The issue I faced is because the useful bash function relies on BASH_SOURCE[0] to get the full path to the file being sourced, and the BASH_SOURCE is obviously not available in zsh.

partial solution: detect if we're on zsh or bash

I used the ZSH_VERSION to check if I'm on zsh.

if [ -n $ZSH_VERSION ]; then
  # assume we're on zsh
elif [ -n $BASH_VERSION ]; then
  # assume we're on bash
else
  # assume POSIX
fi

partial solution: zsh equivalent to BASH_SOURCE[0]

According this StackOverflow answer, the zshell way to get the script path is with ${(%):-%x}, which actually works great.

if [ -n $ZSH_VERSION ]; then
  SCRIPT_FULLPATH="${(%):-%x}"
elif [ -n $BASH_VERSION ]; then
  SCRIPT_FULLPATH="${BASH_SOURCE[0]}"
else
  SCRIPT_FULLPATH=/hardcoded/path
fi

This works, but there's a problem: the ${(%):-%x} is not a valid bash expression, and its presence in a script crashes #shfmt. 🙁

solution: mask invalid bash expression from shfmt

In order to "mask" the invalid-but-useful zshell expression from shfmt I used an alias.

if [ -n "$ZSH_VERSION" ]; then
  alias get_zsh_source='echo "${(%):-%x}"'
  SCRIPT_FULLPATH="$(get_zsh_source)"
elif [ -n "$BASH_VERSION" ]; then
  SCRIPT_FULLPATH="${BASH_SOURCE[0]}"
else
  SCRIPT_FULLPATH=/hardcoded/path
fi

And this is enough to fix the shfmt crash.