ZSH Config Switching
If you want to test different zsh configuration frameworks (oh-my-zsh, zprezto, etc) and switch between them, your best bet is using symbolic links for ~/.zsh
, ~/.zshrc
, ~/.zlogin
, ~/.zlogout
, ~/.zprofile
, and ~/.zshenv
. You may want to create a shell scripts for each framework to create those symlinks for faster switching.
Put your framework configurations in their own folders. For each framework.
- Install the framework in its own folder if possible, otherwise
- If the framework forces installation to
~/.zsh
, then
- Protect the current
~/.zsh
first. Either
- remove the
~/.zsh
symlink; rm ~/.zsh
, or
- move the
~/.zsh
folder; mv ~/.zsh ~/.zsh.backup
- Run the framework installer.
- Move the framework folder to its own directory. e.g.
mv ~/.zsh ~/.oh-my-zsh
.
- Repeat for each framework.
Once done, create a shell script for each framework to create the necessary symlinks. Here's an example for zprezto, since I already use it.
$ mkdir ~/bin
$ cat <<EOF > ~/bin/use-zprezto
#!/bin/bash
SYMLINKS=".zsh .zshrc .zshlogin .zshlogout .zshprofile .zpreztorc .zshenv .zshrc"
CONFIG_HOME="$HOME/.zprezto"
# check for unexpected error conditions
for sym in $SYMLINKS; do
# report an error and quit if $sym exists and is not a symlink
[[ -e "$HOME/$sym" -a ! -h "$HOME/$sym" ]] && { echo "error: '$HOME/$sym' is not a symlink!"; return 1; }
done
# now create the symlinks now that nothing should go wrong
for sym in $SYMLINKS; do
# remove old symlink if it exists
[[ -h "$HOME/$sym" ]] && rm -f "$HOME/$sym"
# create new symlink
ln -s "$CONFIG_HOME/$sym" "$HOME/$sym"
done
# uncomment next line to start a new zsh shell. CAUTION: each call is a zsh shell inside a zsh shell. Too many calls will put you in limbo :D
#/usr/bin/env zsh
EOF
$ chmod 700 ~/bin/use-zprezto
This script is fairly simple and relies on the fact that all my symlinks are organized with the same pattern. You can copy&paste the remove and create lines after the loop for symlinks you have that don't follow the pattern.
Once done, use ~/bin/use-zprezto
--or ~/bin/use-whatever
--to switch between zsh frameworks.
Note that changes only take effect in new zsh shells, not existing shells.
Shell Switching
It's a bit dangerous, but if you're so inclined, you can use a symlink for your shell command and set the symlink as your default shell. You can then follow the use-*
script method above to change your default shell.
As an example with zsh...
$ mkdir ~/bin
$ cat <<EOF > ~/bin/use-zsh
#!/bin/bash
# check for valid shell symlink
if [[ ! -h "$HOME/.shell" ]]; then
echo "error: $HOME/.shell is not a symlink!"
return 1
fi
# remove existing shell symlink if it exists
[[ -h "$HOME/.shell" ]] && rm -f "$HOME/.shell"
# create new shell symlink, but warn user if this fails!
if ! ln -s /usr/bin/zsh "$HOME/.shell"; then
echo "ERROR: failed to create $HOME/.shell symlink. Manually create the symlink or future logins will fail!."
return 2
fi
EOF
$ chmod 700 ~/bin/use-zsh
The reason this is dangerous is that you cannot login under a user if the shell stored in /etc/passwd
is not a valid program. So you can lock yourself out of your account if you're not careful; i.e. your ~/.shell
symlink is broke or doesn't point to an interactive program. You're welcome to try this with a user account, but this is NOT RECOMMENDED for your root
account.
If you still want to continue, then
$ ~/bin/use-zsh # ensures ~/.shell exists for chsh
$ echo "$HOME/.shell | sudo tee -a /etc/shells # add symlink to system's list of valid shells
$ chsh -s ~/.shell # changes default shell in /etc/passwd for $USER
zsh
? oroh-my-zsh
? which?