how can I use bash as my login shell when my sysadmin refuses to let me change it

When you log in, the file ~/.profile is read by the login shell (ksh for you). You can instruct that login shell to replace itself by bash. You should take some precautions:

  • Only replace the login shell if it's interactive. This is important: otherwise, logging in in graphic mode may not work (this is system-dependent: some but not all systems read ~/.profile when logging in through xdm or similar), and idioms such as ssh foo '. ~/.profile; mycommand' will fail.
  • Check that bash is available, so that you can still log in if the executable isn't there for some reason.

You have a choice whether to run bash as a login shell or not. The only major difference in making it a login shell is that it'll load ~/.bash_profile or ~/.profile. So if you run bash as login shell, be very careful to have a ~/.bash_profile or take care not to execute bash recursively from ~/.profile. There is no real advantage of having ~/.profile executed by bash rather than ksh, so I'd recommend not doing it.

Also set the SHELL environment variable to bash, so that programs such as terminal emulators will invoke that shell.

Here's code to switch to bash. Put it at the end of ~/.profile.

case $- in
  *i*)
    # Interactive session. Try switching to bash.
    if [ -z "$BASH" ]; then # do nothing if running under bash already
      bash=$(command -v bash)
      if [ -x "$bash" ]; then
        export SHELL="$bash"
        exec "$bash"
      fi
    fi
esac

This is slightly kludgey, but you can cause bash to be the shell you're using upon login by creating a .profile file in your home directory, containing

SHELL=`type -P bash`
exec bash -l

This will cause the ksh session to be replaced with a bash session. You won't have to type exit (or ^D) twice, as you would if you manually started a new bash session every time you logged in. And typing

echo $SHELL

will even return the path to bash.


Giles' answer should have the -l flag added when executing bash, so that any login profile scripts will be sourced in the new bash shell. (For example anything in /etc/profile.d/ on RHEL). The script should then be:

case $- in
  *i*)
    # Interactive session. Try switching to bash.
    if [ -z "$BASH" ]; then # do nothing if running under bash already
      bash=$(command -v bash)
      if [ -x "$bash" ]; then
        export SHELL="$bash"
        exec "$bash" -l
      fi
    fi
esac