123 lines
3.8 KiB
Bash
123 lines
3.8 KiB
Bash
#!/usr/bin/env zsh
|
|
|
|
eval "$_z4h_opt"
|
|
|
|
local user=${(%):-%n}
|
|
[[ -n $user && -r /etc/shells && $_z4h_exe == /* && -x $_z4h_exe &&
|
|
$user != cloudshell-user && -t 0 && -t 1 && -t 2 ]] || return 0
|
|
|
|
if [[ $OSTYPE == linux* ]]; then
|
|
[[ -r /etc/passwd ]] || return 0
|
|
|
|
if (( ! $+commands[chsh] )); then
|
|
[[ $+commands[sudo] == 1 || -w /etc ]] || return 0
|
|
fi
|
|
|
|
local passwd
|
|
passwd="$(</etc/passwd)" || return '_z4h_err()'
|
|
|
|
local -a match mbegin mend
|
|
[[ $passwd == (#b)*((#s)|$'\n')$user:[^$'\n']#:([^:]##)((#e)|$'\n')* ]] || return 0
|
|
local login_shell=$match[2]
|
|
elif [[ $OSTYPE == darwin* ]]; then
|
|
(( $+commands[dscl] && $+commands[chsh] )) || return 0
|
|
local login_shell
|
|
login_shell=$(dscl . -read ~/ UserShell) || return '_z4h_err()'
|
|
[[ $login_shell == 'UserShell: /'* ]] || return '_z4h_err()'
|
|
login_shell=${login_shell#UserShell: }
|
|
else
|
|
return 0
|
|
fi
|
|
|
|
[[ -x $login_shell && ! $login_shell -ef $_z4h_exe ]] || return 0
|
|
|
|
local -a shells
|
|
shells=(${(f)"$(</etc/shells)"}) || return '_z4h_err()'
|
|
local my_shell=$shells[(re)$_z4h_exe]
|
|
if [[ -z $my_shell ]]; then
|
|
local shell
|
|
for shell in $shells; do
|
|
if [[ $shell -ef $_z4h_exe ]]; then
|
|
my_shell=$shell
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
[[ -n $my_shell || $+commands[sudo] == 1 || -w /etc/shells ]] || return 0
|
|
|
|
-z4h-flowing -- %F{3}z4h%f: login shell isn\'t the same as this shell
|
|
print -Pr -- ""
|
|
print -Pr -- " user %F{3}${user//\%/%%}%f"
|
|
print -Pr -- " login shell %F{2}${login_shell//\%/%%}%f"
|
|
print -Pr -- " this shell %F{2}${${my_shell:-$_z4h_exe}//\%/%%}%f"
|
|
print -Pr -- ""
|
|
-z4h-flowing -- Change login shell of "%F{3}${user//\%/%%}%f" to "%F{2}${${my_shell:-$_z4h_exe}//\%/%%}%f?"
|
|
print -Pr -- ""
|
|
print -Pr -- " %B(y)%b Yes. %BRecommended%b."
|
|
print -Pr -- " %B(n)%b No."
|
|
print -Pr -- ""
|
|
|
|
(
|
|
trap '' INT
|
|
(
|
|
local -i error
|
|
while true; do
|
|
if (( error )); then
|
|
print -Pr -- ''
|
|
print -Pr -- 'Bummer! Try again?'
|
|
print -Pr -- ""
|
|
print -Pr -- " %B(y)%b Yes."
|
|
print -Pr -- " %B(n)%b No."
|
|
print -Pr -- ""
|
|
fi
|
|
print -Prn -- "%BChoice [yn]:%b "
|
|
{
|
|
read -k choice || return
|
|
} always {
|
|
[[ $choice == $'\n' ]] || print
|
|
}
|
|
if [[ $choice == (n|N) ]]; then
|
|
print
|
|
print -rn >$Z4H/stickycache/no-chsh || return '_z4h_err()'
|
|
local home=~
|
|
local zdotdir=${${${(q)ZDOTDIR}/#${(q)home}/'~'}//\%/%%}
|
|
print -Pr -- "Won't ask again unless %U\$Z4H/stickycache/no-chsh%u is deleted."
|
|
return 1
|
|
fi
|
|
[[ $choice == $'\n' ]] && continue
|
|
if [[ $choice != (y|Y) ]]; then
|
|
print -Pr -- '%F{3}z4h%f: invalid choice: '${(q-)choice//\%/%%}
|
|
continue
|
|
fi
|
|
error=1
|
|
print
|
|
if [[ -z $my_shell ]]; then
|
|
print -Pr -- "Adding %F{2}${_z4h_exe//\%/%%}%f to %U/etc/shells%u."
|
|
local precmd=(command)
|
|
[[ -w /etc/shells ]] || precmd+=(sudo)
|
|
$precmd tee -a /etc/shells >/dev/null <<<$_z4h_exe || continue
|
|
my_shell=$_z4h_exe
|
|
(( $#precmd == 1 )) || print
|
|
fi
|
|
print -Pr -- "Changing login shell to %F{2}${my_shell//\%/%%}%f."
|
|
if (( $+commands[chsh] )); then
|
|
command chsh -s $my_shell || continue
|
|
else
|
|
local MATCH MBEGIN MEND
|
|
local p=("${(@)${(@f)passwd}/#%(#m)$user:*/${MATCH%:*}:$my_shell}")
|
|
if [[ ${(F)p} == $passwd ]]; then
|
|
print -Pru2 -- '%F{3}z4h%f: %F{1}internal error%f'
|
|
return '_z4h_err()'
|
|
fi
|
|
local precmd=(command)
|
|
[[ -w /etc ]] || precmd+=(sudo)
|
|
$precmd tee -- /etc/passwd.bak.$$ >/dev/null <<<${(F)p} || continue
|
|
$precmd mv -f -- /etc/passwd.bak.$$ /etc/passwd || continue
|
|
fi
|
|
print -Pr -- "Changed login shell of %F{3}${user//\%/%%}%f to %F{2}${my_shell//\%/%%}%f."
|
|
print
|
|
return 0
|
|
done
|
|
)
|
|
) && export SHELL=${my_shell:-$_z4h_exe}
|