How to get shell to self-detect using zsh or bash

BashZshSh

Bash Problem Overview


I've a question on how to tell which shell the user is using. Suppose a script that if the user is using zsh, then put PATH to his .zshrc and if using bash should put in .bashrc. And set rvmrc accordingly.

#!/usr/bin/env bash
export PATH='/usr/local/bin:$PATH' >> ~/.zshrc
source ~/.zshrc

I've tried the following but it does not work : (

if [[ $0 == "bash" ]]; then
  export PATH='/usr/local/bin:$PATH' >> ~/.bashrc
elif [[ $0 == "zsh" ]]; then
  export PATH='/usr/local/bin:$PATH' >> ~/.zshrc
fi

# ... more commands ...

if [[ $0 == "bash" ]]; then
  [[ -s '/Users/`whoami`/.rvm/scripts/rvm' ]] && source '/Users/`whoami`/.rvm/scripts/rvm' >> ~/.bashrc
  source ~/.bashrc
elif [[ $0 == "zsh" ]]; then
  [[ -s '/Users/`whoami`/.rvm/scripts/rvm' ]] && source '/Users/`whoami`/.rvm/scripts/rvm' >> ~/.zshrc
  source ~/.zshrc
fi

Bash Solutions


Solution 1 - Bash

If the shell is Zsh, the variable $ZSH_VERSION is defined. Likewise for Bash and $BASH_VERSION.

if [ -n "$ZSH_VERSION" ]; then
   # assume Zsh
elif [ -n "$BASH_VERSION" ]; then
   # assume Bash
else
   # assume something else
fi

However, these variables only tell you which shell is being used to run the above code. So you would have to source this fragment in the user's shell.

As an alternative, you could use the $SHELL environment variable (which should contain absolute path to the user's preferred shell) and guess the shell from the value of that variable:

case $SHELL in
*/zsh) 
   # assume Zsh
   ;;
*/bash)
   # assume Bash
   ;;
*)
   # assume something else
esac

Of course the above will fail when /bin/sh is a symlink to /bin/bash.

If you want to rely on $SHELL, it is safer to actually execute some code:

if [ -n "`$SHELL -c 'echo $ZSH_VERSION'`" ]; then
   # assume Zsh
elif [ -n "`$SHELL -c 'echo $BASH_VERSION'`" ]; then
   # assume Bash
else
   # assume something else
fi

This last suggestion can be run from a script regardless of which shell is used to run the script.

Solution 2 - Bash

Just do echo $0 it says -zsh if it's zsh and -bash if it's bash

EDIT: Sometimes it returns -zsh and sometimes zsh and the same with bash, idk why.

Solution 3 - Bash

A word of warning: the question you seem to have asked, the question you meant to ask, and the question you should have asked are three different things.

“Which shell the user is using” is ambiguous. Your attempt looks like you're trying to determine which shell is executing your script. That's always going to be whatever you put in the #! line of the script, unless you meant your users to edit that script, so this isn't useful to you.

What you meant to ask, I think, is what the user's favorite shell is. This can't be determined fully reliably, but you can cover most cases. Check the SHELL environment variable. If it contains fish, zsh, bash, ksh or tcsh, the user's favorite shell is probably that shell. However, this is the wrong question for your problem.

Files like .bashrc, .zshrc, .cshrc and so on are shell initialization files. They are not the right place to define environment variables. An environment variable defined there would only be available in a terminal where the user launched that shell and not in programs started from a GUI. The definition would also override any customization the user may have done in a subsession.

The right place to define an environment variable is in a session startup file. This is mostly unrelated to the user's choice of shell. Unfortunately, there's no single place to define environment variables. On a lot of systems, ~/.profile will work, but this is not universal. See https://unix.stackexchange.com/questions/4621/correctly-setting-environment and the other posts I link to there for a longer discussion.

Solution 4 - Bash

You can simply try

 echo $SHELL

Solution 5 - Bash

An alternative, might not work for all shells.

for x in $(ps -p $$)
do
  ans=$x
done
echo $ans

Solution 6 - Bash

the other answers fail with set -u

  if [ ! -z ${ZSH_VERSION+x} ]; then
    echo "this is zsh"
    echo ${(%):-%x}
  elif [ ! -z ${BASH_VERSION+x} ]; then
    echo "this is bash"
    echo $BASH_SOURCE
  else
    echo "not recognized"
  fi

Solution 7 - Bash

Myself having a similar problem, settled for:

_shell="$(ps -p $$ --no-headers -o comm=)"                                                                                                       
if [[ $_shell == "zsh" ]]; then                                                                                                                  
    read -q -s "?Do it?: "                                                                                                                    
fi                                                                                                                                               
elif [[ $_shell == "bash" || $_shell == "sh" ]]; then                                                                                              
    read -n 1 -s -p "Do it [y/n] "                                                                                                            
fi                                                                                                                                               

Solution 8 - Bash

Here is how I am doing it based on a previous answer from Gilles :

if [ -n "$ZSH_VERSION" ]; then
  SHELL_PROFILE="$HOME/.zprofile"
else
  SHELL_PROFILE="$HOME/.bash_profile"
fi
echo "export VAR1=whatever" >> $SHELL_PROFILE
echo "INFO: Refreshing your shell profile: $SHELL_PROFILE"
if [ -n "$ZSH_VERSION" ]; then
  exec zsh --login
else
  source $SHELL_PROFILE
fi

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJuanito FatasView Question on Stackoverflow
Solution 1 - BashadlView Answer on Stackoverflow
Solution 2 - Bash2xsaikoView Answer on Stackoverflow
Solution 3 - BashGilles 'SO- stop being evil'View Answer on Stackoverflow
Solution 4 - BashPushan GuptaView Answer on Stackoverflow
Solution 5 - BashpizzaView Answer on Stackoverflow
Solution 6 - BashtimotheecourView Answer on Stackoverflow
Solution 7 - BashagathodaimonView Answer on Stackoverflow
Solution 8 - BashdjangofanView Answer on Stackoverflow