env -i executes the specified command with an empty environment.
bash -c … executes the argument of the
-c option (the
…) as a bash code snippet.
bash -c 'echo $SHELL $HOME $USER' is equivalent to
echo $SHELL $HOME $USER, because running bash doesn't modify these variables (at least as long as they're initially set).
env -i bash -c 'echo $SHELL $HOME $USER' runs
bash with the arguments
echo $SHELL $HOME $USER, and with an empty environment. When bash starts, it sets some shell variables, including
SHELL (which is only set as a shell variable, not exported in the environment of any child program that bash might start). Thus, when bash parses and expands the command
echo $SHELL $HOME $USER, the variables
USER are unset but
SHELL is set to
/bin/sh (I don't know why bash does this), and this command displays
/bin/sh followed by two spaces.
The single quotes around the argument of
bash -c ensure that the text within the quotes is not expanded by the shell from which you run
env -i bash -c '…', so that text is passed as-is to the bash subprocess.