I want to have different shells in different jails. It looks like there is a bug that prevents that.
How to solve?
1. What if starting jexec with a path to the shell? simple! *even you see you are using bash…. (make an alias)
#jexec 1 /usr/local/bin/bash
#echo $SHELL
/bin/csh
2. What if to set up a default shell by chsh inside a jail
#jexec 1
#chsh -s /usr/local/bin/bash
#exit
#jexec 1
#echo $SHELL
/bin/csh
3. What if modify a ~/.profile
SHELL=/usr/local/bin/bash
export SHELL
No. No. No.
Let’s have a closer look what is going on:
By analysing https://github.com/freebsd/freebsd/blob/master/usr.sbin/jexec/jexec.c#L132 you can clearly see that exec shell would be defined if pw_shell is set and if not set it uses default hardcoded /bin/sh ( or /rescure/sh )
setenv("SHELL", *pwd->pw_shell ? pwd->pw_shell : _PATH_BSHELL, 1);
The constant _PATH_BSHELL is defined inside: :https://github.com/freebsd/freebsd/blob/1d6e4247415d264485ee94b59fdbc12e0c566fd0/include/paths.h#L47
#define _PATH_BSHELL "/bin/sh"
This gives the idea: You have to have change shell env on the master before starting jexec shell. This is not ideal but let’s test:
#setenv SHELL /usr/local/bin/bash
#jexec 1
#echo $SHELL
/usr/local/bin/bash
Wow! This is great and works! Lets make it permanently on master:
#chsh -s /usr/local/bin/bash
Yes? Wrong. Such a solution requires you to have installed your favourite shell on master and then inside a jail otherwise you will face this:
#jexec 2
jexec: execlp: /usr/local/bin/bash: No such file or directory
In worst case scenario your default user on master would end up in /bin/sh. You could install missing scripts…
#jexec mycleantestjail
jexec: execlp: /usr/local/bin/fish: No such file or directory
#jexec mycleantestjail pkg install fish -y
#jexec mycleantestjail
The solution script
Even you start shell by aliases like bash or fish – default $SHELL is going to be CSH. This might have implications on other application running inside jails. For example, Midnight Commander has a build-in shell that relay on variable $SHELL. This means when you start mc and then access shell it would be default one ( probably /bin/csh )
The best solution would be to update jexec.c logic to use default $SHELL from a user from inside a jail. C fix possibly should be checking /etc/shells or /etc/pw.conf and not to rely on master default shell. Until then is to modify shell by a script before it gets lunched. It only checks for user root. Any suggestions welcome.
#!/bin/csh
set D=`jexec $1 pw usershow root | awk -F":" '{print $10}'`
set O=`pw usershow root | awk -F":" '{print $10}'`
setenv SHELL ${D}
jexec $*
setenv SHELL ${O}
Save it to jexec2.sh then add to your ~/.cshrc
alias jexec2 ./<path-to-yourfile>/jexec2.sh