fix the silent death after installing zsh

Reported from a fresh Hetzner VPS: the run stopped dead right after apt finished
installing zsh, printing nothing at all — just install.sh's "machine setup did not
finish".

install_oh_my_zsh carried a comment saying it "Returns 0 whatever happens". It did
not. Under `set -e` a failing command inside a function aborts the SHELL at that
line when the function is called plainly; `return 0` underneath is never reached.
The command is also `>/dev/null 2>&1`, so the cause was invisible — which is why
the transcript just ends.

`|| true` is what actually makes it non-fatal. The file already uses that idiom
correctly in four other places, so this was a slip rather than a misunderstanding.

set_login_shell had the identical bug on `chsh`, which the same run would have hit
on the very next question. Fixed differently and deliberately: `|| true` there
would let the caller announce a login shell that was never set, so it returns
chsh's real status and the CALLER guards the call — which is also what keeps set -e
out of it. A refusal now reports, names the manual chsh command, and carries on,
because a machine with zsh installed and bash at login still works.

Does not explain WHY oh-my-zsh failed on that host — the output was discarded. It
will now say "oh-my-zsh did not install" and continue, which is enough to see it.

Verified: bash -n on both files, and a reduced case proving broken() exits 1 while
fixed() survives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 06:23:45 +00:00
co-authored by Claude Opus 5
parent 6c13e0d8f6
commit 4c33ef7206
2 changed files with 33 additions and 14 deletions
+13 -3
View File
@@ -2217,10 +2217,20 @@ if ! skip; then
echo ""
echo " ${USERNAME}'s login shell is ${SHELL_NOW}. Changing it to zsh takes"
echo " effect at the next login, and does not affect this session."
# Guarded, not bare: `chsh` can refuse — a PAM policy, a shell missing from
# /etc/shells, an account whose password field blocks it — and a bare call would
# end the run there under `set -e`. Reported instead, because a machine with the
# right shell installed and the wrong one at login still works.
if confirm "Make zsh the login shell?"; then
set_login_shell "$(command -v zsh)"
ok "login shell is now $(user_login_shell)"
SUMMARY+=("Shell: login shell set to zsh")
if set_login_shell "$(command -v zsh)"; then
ok "login shell is now $(user_login_shell)"
SUMMARY+=("Shell: login shell set to zsh")
else
warn "chsh refused — login shell is still $(user_login_shell)"
echo " Change it later with: chsh -s $(command -v zsh) ${USERNAME}"
ERRORS+=("Shell: chsh refused, login shell left as $(user_login_shell)")
SUMMARY+=("Shell: login shell NOT changed")
fi
else
warn "left as ${SHELL_NOW}"
SUMMARY+=("Shell: login shell left as ${SHELL_NOW}")