Solved Is it possible to default to mksh, while automatically falling to sh

Is it possible to default to mksh or any other shell, while automatically falling to sh when that shell port isn't available on my system, without needing to go into single user mode? The chsh (chpass(1)) command only offers one shell setting here.

This usually isn't an issue, but it becomes a major issue on system upgrades. When that happens, mksh, zsh or other shell becomes unavailable, and it requires rebooting into single user mode to fix this. It would be more convenient to fall back to something that's in the base system to fix this, when it occurs.

sh lacks, and I have to keep configuration updates for csh when I'm using root. CSH has convenient functions, but its configuration is so different than sh. I ended up leaving in csh for root.

Come to think of it, the /rescue/ directory could come in handy, but it would use the same shell as my system. I'm used to using the rescue directory from single user mode, but it seems to work in multiuser mode too. Then, I would only need this shell fallback functionality for the root account, since to fix a system, I would use root. Currently, I'll have to maintain cshsrc configuration, which is extra upkeep from the traditional FreeBSD Bourne shells.

Or, I could go back to using CSH for all of my interactive user shells, as I've once done. Another option, is to use a shell which comes with root as the default, then manually switching to mksh or other shell, each time.
 
Its generally not a good idea to change the default user shell for root. In the passwd file you can specify default shell on a per-user basis, but you'll run into problems with system scripts if you change the root shell.

That's not to say you can't or shouldn't use the shell you like, but either do it for a non-root user, or when you login as root under the default shell, then execute your choice shell manually.

Since well conforming scripts should start with #! /whatever/shell they would run under whatever interpretter if specified.
 
Replacing it with a C program could do it. First try to start mksh and only follow with sh if it returns non-zero. I didn't try it, maybe the shells setting doesn't accept strange executables or the shell must be officially installed and registered as package.
 
I have used a statically linked pdksh for my FreeBSD root account since approximately 1997. No issues. But you have an obligation to keep it patched, assuming that security matters.

I have never had a shell disappear on a system upgrade.

I make the shells/pdksh port, with the static option, and allow it to install in /usr/local/bin/ksh. I then copy it to /bin/ksh, and add an entry to /etc/shells. I then purge the port (make clean deinstall rmconfig, and make install the dynamically linked version:
Code:
[gunsynd.156] $ file /bin/ksh
/bin/ksh: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), statically linked, for FreeBSD 13.2, FreeBSD-style, stripped
[gunsynd.157] $ file /usr/local/bin/ksh
/usr/local/bin/ksh: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 13.2, FreeBSD-style, stripped
[gunsynd.158] $ strings /bin/ksh | grep KSH
KSH_VERSION
@(#)PD KSH v5.2.14.2 99/07/13.2
[gunsynd.159] $ strings /usr/local/bin/ksh | grep KSH
KSH_VERSION
@(#)PD KSH v5.2.14.2 99/07/13.2
[gunsynd.160] $ grep ksh /etc/shells
/bin/ksh
/usr/local/bin/ksh
[gunsynd.165] $ grep "^root" /etc/passwd
root:*:0:0:Charlie &:/root:/bin/ksh
 
I have
if ( -X zsh && -f ~/.Use_zsh ) exec zsh
at the end of my ~/.tcshrc.mine, where ~/.Use_zsh is an empty file to state I want to use zsh as my command line shell.

This way, I can use zsh when I have ~/.Use_zsh, keeping my default shell to be in-base /bin/tcsh, and when I want to switch back to [t]csh, just rename or delete ~/.Use_zsh is sufficient. And if zsh does not exists anywhere in the path, tcsh is used as is.

Note that if you want your fall-back shell to be /bin/sh and/or want different command line shell, you need to adapt the line.
 
You could set toor account to use mksh, that would let root account default to sh.
That is exactly what I do since I've switched to FreeBSD I use intensively the toor account and I love it (I can use doas+normal user but most of the time I prefer to switch to an account with high privileges), I've set a toor account on most of my boxes and VMs to zsh. The root acount is untouched basically, it's set to sh, so in case something bad happens no worries.
It's just something to keep in mind every time you need root privileges, instead of typing su -, you type su - toor, then you have your favorite shell with high privileges, I am not entirely sure that is what you want but it sounds very similar.
 
Is it possible to default to mksh or any other shell, while automatically falling to sh when that shell port isn't available on my system, without needing to go into single user mode? The chsh (chpass(1)) command only offers one shell setting here.

This usually isn't an issue, but it becomes a major issue on system upgrades. When that happens, mksh, zsh or other shell becomes unavailable, and it requires rebooting into single user mode to fix this. It would be more convenient to fall back to something that's in the base system to fix this, when it occurs.

sh lacks, and I have to keep configuration updates for csh when I'm using root. CSH has convenient functions, but its configuration is so different than sh. I ended up leaving in csh for root.

Come to think of it, the /rescue/ directory could come in handy, but it would use the same shell as my system. I'm used to using the rescue directory from single user mode, but it seems to work in multiuser mode too. Then, I would only need this shell fallback functionality for the root account, since to fix a system, I would use root. Currently, I'll have to maintain cshsrc configuration, which is extra upkeep from the traditional FreeBSD Bourne shells.

Or, I could go back to using CSH for all of my interactive user shells, as I've once done. Another option, is to use a shell which comes with root as the default, then manually switching to mksh or other shell, each time.
You mean like this?

Code:
case $(tty) in
/dev/console|/dev/ttyv?|/dev/ttyd?)
        echo Using default shell of $SHELL
        ;;
*)      if [ -x /usr/local/bin/bash -a ! -f /tmp/root/xyzzy ]; then
                echo starting bash shell
                OSHELL=$SHELL
                SHELL=/usr/local/bin/bash
                export SHELL
                $SHELL < /dev/null && exec $SHELL
                SHELL=$OSHELL
                unset OSHELL
                echo Unable to execute /usr/local/bin/bash or not found, using default shell of $SHELL
        else
                echo Using default shell of $SHELL
        fi
        ;;
esac
 
You could set toor account to use mksh, that would let root account default to sh.
instead of typing su -, you type su - toor, then you have your favorite shell with high privileges, I am not entirely sure that is what you want but it sounds very similar.
From that explanation about toor, I looked to find Thread solved-toor-account.45584. On mine, it wouldn't let me go from a regular user account directly to toor, due to permissions, but I logged into root, and was able to su toor to get my preferred shell. I can do that, when I get tired of retyping: go from root to toor.

I have never had a shell disappear on a system upgrade.
It had to do, when I needed rescue mode, or when I reinstalled packages, sometimes after a system upgrade, and didn't get a shell running back quick enough. csh and sh are also in the /rescue/ directory. From that thread, the reasoning is explained in another BSD forum. https://daemonforums.org/showthread.php?t=666

The other ways are automatic through conditional shell scripts, which will work too. I almost just went back to csh for everything, because sh is too minimal. My purposes are less of traditional compatibility shell programming, and more of interactive use. I may still go back to csh for everything, and may use some combination of above solutions.
 
Back
Top