42

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. )

2
  • What version of Unix are you using? Are you sure all servers have bash? I learned the hard way in AIX not to change your default shell to bash. If the server does not have bash you can not login.
    – cokedude
    Apr 22, 2021 at 14:59
  • I'm at a different job now, but if I recall correctly these were RedHat boxes. They definitely had bash. It was an IBM shop, to some extent, so they probably also had some old moldy AIX boxes lying around. Perhaps that accounts for the sysadmins using ksh.
    – iconoclast
    Apr 22, 2021 at 23:57

5 Answers 5

74

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
2
  • 19
    Excellent answer! stackexchange needs a Send A Beer button: this would be a time I'd use it.
    – iconoclast
    Aug 30, 2012 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, 2018 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.

13
  • 3
    you could of course change $SHELL fairly easily by adding a line to do so before the exec.
    – derobert
    Aug 29, 2012 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, 2012 at 21:48
  • 1
    One last comment: type is recommended over which.
    – jw013
    Aug 29, 2012 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, 2012 at 6:21
  • 1
    @user1129682 not if there is ~/.bash_profile or ~/.bash_login Aug 30, 2012 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
2
  • Can you explain why you say to add the -l option? I have using this for months without it with no issues.
    – cokedude
    Sep 24, 2019 at 22:22
  • Can you explain the -l option please?
    – cokedude
    Apr 22, 2021 at 8:32
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
  • 1
    Doesn't usermod require admin rights, and the question is " ... when my admin refuses ..." ? Jun 22, 2016 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.