17

Whenever I run sudo su from my normal zsh (which uses the oh-my-zsh framework), I'm forced to use the old Bourne shell (sh) by default (obviously; this is standard behaviour on most *nix-like systems). If I run zsh from within sh after running sudo su, I get the Z shell, but without the improvements from oh-my-zsh.

Is there any way to change the shell sudo su launches to zsh? If so, is it possible to also have that instance of zsh launch using oh-my-zsh?

I'm using OS X 10.8.4.

Jules
  • 698
  • 4
  • 10
  • 26

4 Answers4

24

Another way to execute an interactive shell as the superuser is sudo -s, which uses $SHELL as the shell.

As the comments in the other answer mentioned, su -s /path/to/zsh doesn't work in OS X.

OS X doesn't support changing login shells in /etc/passwd either, but you can use dscl:

$ dscl . -read /Users/root UserShell
/bin/sh
$ sudo dscl . -change /Users/root UserShell /bin/sh /bin/zsh
$ dscl . -read /Users/root UserShell
/bin/zsh
$ sudo su
My-iMac# echo $0
zsh
My-iMac# exit
$ sudo dscl . -change /Users/root UserShell /bin/zsh /bin/sh
$ 

/bin/sh is not a Bourne shell anymore on most platforms. It is a POSIX-compliant version of bash in OS X and dash in Ubuntu.

Lri
  • 40,894
  • 7
  • 119
  • 157
  • This is what I would think the question wanted. It's definitely what worked for me; thank you so much! *edit* i see what he wanted now - I don't think this is what he wanted, so I can't fairly upvote it for this question, but I think you deserve a medal anyway. You had the answer to _my_ question! – Wyatt Ward Jan 31 '14 at 22:31
5

From the su manpage, there are two ways you can accomplish this.


The first method is to simply use the -s or --shell flag (assuming you are using a *NIX-based OS with a version of su that supports this argument), followed by the path to the shell of your choice. If the passed shell cannot be found, su reverts to the following method, and failing that, will attempt to invoke /bin/sh.

For example, you can force su to launch zsh (assuming it exists in /bin/zsh) as:

sudo su --shell /bin/zsh

The second method is to modify the default shell specified for the root user (be careful!). This can be done by editing the file /etc/passwd and changing the shell specified for the root user. To see what shell is specified by default, you can run the following command (assuming the superuser is root):

sudo grep root /etc/passwd 

The command should output something like root:x:0:0:root:/root:/bin/bash. You can simply change the /bin/bash (or whatever is set in your system) to point to zsh instead.

terdon
  • 52,568
  • 14
  • 124
  • 170
Breakthrough
  • 34,227
  • 10
  • 105
  • 149
  • 3
    As always, be careful about changing root's shell. You don't want to be in single user mode, and have a root shell that needs /usr when it's broken. At lease make sure your new shell has no more filesystem dependencies than the one you're replacing – Rich Homolka Jul 31 '13 at 18:11
  • Running `sudo su -s /bin/zsh` (or using `--shell`) returns `su: illegal option -- s`. I'm on OS X 10.8.4; does OS X take a different command? – Jules Jul 31 '13 at 18:15
  • @JulesMazur what is the output of `cat /etc/shells`? Technically only shells allowed in that file will be launched, although the `su` manpage says this shouldn't matter if `su` is called by root :S – Breakthrough Jul 31 '13 at 18:16
  • `cat /etc/shells` returns `/bin/zsh` as an acceptable shell. – Jules Jul 31 '13 at 18:18
  • @JulesMazur ah, sorry - I just saw the [su manpage](https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man1/su.1.html) from Apple's site (I don't own any Apple products, I'm running Linux) doesn't specify the `-s` option... However, you may have some luck experimenting with the environment switches (e.g. `-m`) after setting your `$SHELL` variable. – Breakthrough Jul 31 '13 at 18:20
  • 2
    @JulesMazur please remember to always include your OS to avoid this kind of confusion. – terdon Jul 31 '13 at 18:24
  • I've updated `/etc/passwd` to use `zsh`, and running `sudo cat /etc/passwd | grep root` returns `root:*:0:0:System Administrator:/var/root:/bin/zsh`, but running `sudo su` still goes to `sh`. @terdon will do. – Jules Jul 31 '13 at 18:28
  • @JulesMazur sorry, after looking at Apple's `su` manpage, I don't think changing that will do anything. The manpage itself doesn't specify any additional information as to how to specify a default shell (outside of setting the `$SHELL` env. variable). As a workaround, you might just want to do `sudo /bin/zsh` to launch a `zsh` shell as root. – Breakthrough Jul 31 '13 at 18:31
  • I got it working using a disgusting, contorted (but crucially, loop-avoiding) shell script. Thanks! – Jules Jul 31 '13 at 18:40
1

A cleaner way that will also protect your system in case your custom shell is blown up is to create a .profile in root's home directory w/:

if [ -x /opt/local/bin/bash ]; then
    SHELL=/opt/local/bin/bash
    export SHELL
    exec /opt/local/bin/bash
else
    echo /opt/local/bin/bash not found using default shell of $SHELL
fi

Just change the path to the shell you want instead of bash.

cybrhippy
  • 11
  • 1
0

Can be easily done with chpass:

$ sudo chpass -s /bin/zsh
user686249
  • 101
  • 1