37

The unix sysadmin where I'm working is reluctant to give me access to change my login shell from ksh to bash. He has given various excuses, the funniest being that since they write all their scripts for ksh they won't work if I try to run them. I don't know where he gets these ideas, but since I can't convince him, is there any alternative that I have?

(chsh is installed on these machines, but we use public/private keypairs for logging in, and I don't have any password, so when chsh prompts me for a password I have nothing to give it. )

68

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
  • 16
    Excellent answer! stackexchange needs a Send A Beer button: this would be a time I'd use it. – iconoclast Aug 30 '12 at 13:39
  • Thanks first and. .profile only works for login shell (as OP need). I use Remote Desktop Connection of Windows 10 to login a Linux workstation, then open Terminal in gnome. I want zsh while my sysadmin give me bash. In this case, I have to add the snippet in .bashrc instead of .profile. – Weekend Apr 8 '18 at 12:32
12

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.

  • 3
    you could of course change $SHELL fairly easily by adding a line to do so before the exec. – derobert Aug 29 '12 at 21:35
  • 2
    If you want the new shell to also be a login shell you should probably exec bash -l. – jw013 Aug 29 '12 at 21:48
  • 1
    One last comment: type is recommended over which. – jw013 Aug 29 '12 at 22:06
  • 1
    I don't get it! Won't bash also read .profile thus generating an infinite loop? I agree that something along the lines of exec bash is what you want, but you need to make sure you do it only to your login ksh so some if-statements are required! – Bananguin Aug 30 '12 at 6:21
  • 1
    @user1129682 not if there is ~/.bash_profile or ~/.bash_login – Ulrich Dangel Aug 30 '12 at 7:37
4

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
1

An answer for csh/tcsh inspired by the top voted one by @Gilles is

if ( ! $?BASH ) then
  setenv BASH `command -v bash`
endif

if ( $?prompt ) then
  if ( -x "$BASH" ) then
    exec "$BASH"
  endif
endif
0

Solaris:

usermod -s /bin/bash root
  • 1
    Doesn't usermod require admin rights, and the question is " ... when my admin refuses ..." ? – Blessed Geek Jun 22 '16 at 17:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.