Since 4.2BSD, Berkeley UNIX systems have restricted chsh (or a command like it) to change your login shell only to a shell that's listed in the file /etc/shells. That's partly a safety feature, like requiring you to type your old password before you can change to a new one: it keeps other people from giving you a strange login shell as a joke. It's also for security - a way for the system administrator to give a list of shells that are robust enough to run peoples' accounts.
The usual "approved" shells are the Bourne and C shells. If you want to use another shell as your login shell and your system has /etc/shells, ask the system administrator to add your shell. The shell will need to be stored in a secure system directory to make it harder for system crackers to corrupt the shell.
If the system administrator won't approve your login shell, here's a work-around. It lets you log in with an approved shell, then automatically replace the shell with whatever you want. (For background, see article 51.9.)
If your login shell isn't C shell, use chsh or a command like it to change it to the C shell.
If your new shell will be bash, you can skip this step. Otherwise:
In your home directory, make a
hard or symbolic link (18.4)directory,
to your shell.
Use a name starting with a minus sign (-
);
this makes the shell
act like a login shell (51.9).
For example, to make a symbolic link in your home directory named
-ksh to the shell /usr/local/bin/ksh, type this command:
./ |
% |
---|
Add lines to the top of the .cshrc (2.2) file that replace the csh process with your login shell. (The exec (45.7) command replaces a process.)
If you use a Bourne-type shell that reads the .profile file at login time, use lines like these:
TERM su if $? | # OVERRIDE DEFAULT LOGIN C SHELL TO USE ksh. setenv SHELL /usr/local/bin/ksh # IF $TERM SET (BY login OR rlogin), START LOGIN SHELL. # UNFORTUNATELY, THIS MAKES su USE A LOGIN SHELL TOO. if ($?TERM) then cd exec -ksh # USE "LOGIN SHELL" SYMLINK IN $HOME else exec $SHELL endif echo "******** WARNING: exec ksh FAILED ********" |
---|
If your new login shell will be bash, you can replace the line
exec -ksh
above with:
exec $SHELL -login
because bash has a -login option that tells it to act like a login shell. Simple, eh?
If your new login shell is a csh-type shell that also reads .cshrc, you need to add a test to .cshrc that prevents an infinite loop. This test uses the SH_EXECD environment variable (6.1) as a flag:
# OVERRIDE DEFAULT LOGIN C SHELL TO USE tcsh. if (! $?SH_EXECD) then setenv SH_EXECD yes setenv SHELL /usr/local/bin/tcsh # IF $TERM SET (BY login OR rlogin), START LOGIN SHELL. # USE switch, NOT if, DUE TO csh BUG WITH IMBEDDED else. # UNFORTUNATELY, THIS MAKES su USE A LOGIN SHELL TOO. switch ($?TERM) case 1: cd exec -tcsh # USE "LOGIN SHELL" SYMLINK IN $HOME breaksw default: exec $SHELL # USE NON-LOGIN SHELL breaksw endsw echo "******** WARNING: exec tcsh FAILED ********" endif
The C shell may not find your new shell (-ksh
or -tcsh
)
unless you have the current directory (.
) in your
search path (8.7)
(put it at the end of your path!).
You may also be able to use an
absolute pathname (14.2)
to the new shell, but that could hide the leading
minus sign (-
) and the shell might not act like a login shell.
Is there a chance that your new shell might be missing some day? For instance, is it on a network filesystem that might be unavailable? Then it's a good idea to wrap the new code above with a test:
-e |
if (-e |
---|
Test your new setup:
Try commands that start subshells (38.4), like su, rsh, and so on (2.7), to be sure that they start your new shell.
Put the csh command set echo (8.17) at the top of your .cshrc file to be sure your commands there are working.
Type a command that will work only in your new shell (not in a C shell).
Use the
ps (38.5)
command
ps
$$
(on System V, ps
-f
-p
$$
)
to look at your new shell process ($$
is your shell's
process ID number (38.3)).
Before you log out of this shell, try logging in from somewhere else (2.4) to be sure your new shell startup files work.
You're set to go.
If your login shell isn't listed in /etc/shells, the ftp (52.7) program (actually, the ftpd daemon (1.14)) may refuse to transfer files to your account. That's partly to stop ftp access to your system through special accounts that don't have passwords, like sync, who, finger, and so on. If you use the workaround steps above, though, that shouldn't be a problem; you'll have an approved shell listed in /etc/passwd and ftp usually doesn't run your login shell, anyway.
-