diff --git a/tools/install.sh b/tools/install.sh index 3f4de868..4aa49fb6 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -80,18 +80,99 @@ main() { " ~/.zshrc > ~/.zshrc-omztemp mv -f ~/.zshrc-omztemp ~/.zshrc - # If this user's login shell is not already "zsh", attempt to switch. - TEST_CURRENT_SHELL=$(expr "$SHELL" : '.*/\(.*\)') - if [ "$TEST_CURRENT_SHELL" != "zsh" ]; then - # If this platform provides a "chsh" command (not Cygwin), do it, man! - if hash chsh >/dev/null 2>&1; then - printf "${BLUE}Time to change your default shell to zsh!${NORMAL}\n" - chsh -s $(grep /zsh$ /etc/shells | tail -1) - # Else, suggest the user do so manually. + # Do not prompt user unless STDIN file descriptor is bound to TTY, + if [ -t 0 ]; then + TEST_LOGIN_SHELL=$(expr "$SHELL" : '.*/\(.*\)') + if [ "$TEST_LOGIN_SHELL" = "zsh" ]; then + # No need to change login shell. + ENV_ZSH="$SHELL" + # Let's try to change the login shell. else - printf "I can't change your shell automatically because this system does not have chsh.\n" - printf "${BLUE}Please manually change your default shell to zsh!${NORMAL}\n" + # See what zsh (if any) they have in the current environment -- it's probably + # the zsh they prefer, assuming /etc/shells could have multiple zsh entries. + ENV_ZSH="$(which zsh)" # $(type -P zsh) would be better but not POSIX sh + + # Will it blend? + if ! "$ENV_ZSH" -c 'exit 0' >/dev/null 2>&1; then + unset ENV_ZSH + fi + + # Is the environment zsh also in the list of supported login shells? + if [ -n "$ENV_ZSH" ] && grep "^${ENV_ZSH}$" /etc/shells >/dev/null 2>&1; then + printf "${YELLOW}Found ${ENV_ZSH}${NORMAL} ${GREEN}in /etc/shells.${NORMAL}\n" + CHSH_ZSH="$ENV_ZSH" + else + # No? Then let's get the last zsh entry from the list of supported login shells. + # -- We know at least one is in there because of an earlier check in this script. + GREP_ZSH="$(grep /zsh$ /etc/shells | tail -1)" + # Will it blend? + if "$GREP_ZSH" -c 'exit 0' >/dev/null 2>&1; then + # Yep, let's use that zsh entry. + CHSH_ZSH="$GREP_ZSH" + else + # Nope, it's a bogus path. + printf "${RED}I can't change your shell automatically because there is a bad zsh entry in /etc/shells.${NORMAL}\n" + if [ -n "$ENV_ZSH" ]; then + # If the environment zsh is real, suggest they add that to the list of supported login shells. + printf "${BLUE}Consider adding $ENV_ZSH to /etc/shells and then manually change your default shell.${NORMAL}\n" + else + printf "${RED}No real zsh found in the current environment or /etc/shells.${NORMAL}\n" + printf "${RED}You might not have zsh properly installed...${NORMAL}\n" + # OKAY, IT'S GETTIN' WEIRD. BAIL OUT! + exit + fi + fi + fi + + if [ -n "$CHSH_ZSH" ]; then + # If this platform provides a "chsh" command (not Cygwin), do it, man! + if hash chsh >/dev/null 2>&1; then + printf "${BLUE}Time to change your default shell to ${CHSH_ZSH}!${NORMAL}\n" + while true; do + set +e + trap 'CHSH_ZSH_ERRNO=$?' INT + CHSH_ZSH_STDERR="$(chsh -s "$CHSH_ZSH" 2>&1)" + CHSH_ZSH_ERRNO=${CHSH_ZSH_ERRNO-$?} + case $CHSH_ZSH_ERRNO in + 0) + # Great. It worked. + # Update the $SHELL export for this session. + SHELL="$CHSH_ZSH" + break + ;; + 130) + printf "${RED}Change of default login shell has been cancelled!${NORMAL}\n" + printf "${BLUE}To try again, run the following command at any time:\n${NORMAL}" + printf ' %schsh -s "%s"%s\n' "${BLUE}" "$CHSH_ZSH" "${NORMAL}" + break + ;; + *) + case "$CHSH_ZSH_STDERR" in + *Credentials*) + printf "${RED}Wrong password.${NORMAL} ${GREEN}Press CTRL-C to cancel.${NORMAL}\n" + ;; + *) + # Probably best to fall back to the environment zsh if it exists. + if [ -n "$ENV_ZSH" ]; then + unset CHSH_ZSH + fi + break + ;; + esac + ;; + esac + trap - INT + set -e + done + # Else, suggest the user change the login shell manually. + else + printf "I can't change your shell automatically because this system does not have chsh.\n" + printf "${BLUE}Please manually change your default shell to ${CHSH_ZSH}!${NORMAL}\n" + fi + fi fi + else + printf "${BLUE}No TTY specified! Please manually change your default shell to zsh!${NORMAL}\n" fi printf "${GREEN}" @@ -110,7 +191,12 @@ main() { echo 'p.p.s. Get stickers and t-shirts at http://shop.planetargon.com.' echo '' printf "${NORMAL}" - env zsh + + if [ -n "$CHSH_ZSH" ]; then + env "$CHSH_ZSH" + elif [ -n "$ENV_ZSH" ]; then + env "$ENV_ZSH" + fi } main