fix(setup): handle unterminated passwd, make shell change non-fatal
shadow's commonio_open() refuses to modify a user/group database whose last line has no trailing newline, failing with a misleading "cannot open /etc/passwd". Under 'set -e' this aborted the whole setup at the fish step (and would later break docker's groupadd/usermod too). - add ensure_db_trailing_newlines() to normalize /etc/passwd, /etc/group and /etc/shadow before any user/group modification - switch default shell via 'usermod -s' with a 'chsh' fallback, warning instead of aborting the script on failure
This commit is contained in:
@@ -300,13 +300,16 @@ setup_fish() {
|
||||
info "$FISH_PATH already in /etc/shells"
|
||||
fi
|
||||
|
||||
# Change default shell only if not already fish
|
||||
# Change default shell only if not already fish.
|
||||
# Prefer usermod (script-friendly, no TTY/PAM quirks); fall back to chsh.
|
||||
# Never abort the whole setup if this fails — just warn and move on.
|
||||
current_shell="$(getent passwd "$USER" | cut -d: -f7)"
|
||||
if [ "$current_shell" = "$FISH_PATH" ]; then
|
||||
info "fish is already the default shell"
|
||||
else
|
||||
psudo chsh -s "$FISH_PATH" "$USER"
|
||||
elif psudo usermod -s "$FISH_PATH" "$USER" || psudo chsh -s "$FISH_PATH" "$USER"; then
|
||||
success "Default shell changed to fish ($FISH_PATH)"
|
||||
else
|
||||
warn "Could not change default shell to fish — run manually: sudo usermod -s $FISH_PATH $USER"
|
||||
fi
|
||||
|
||||
# For brew-based systems: add brew shellenv to fish config
|
||||
@@ -749,6 +752,24 @@ setup_passwordless_sudo() {
|
||||
esac
|
||||
}
|
||||
|
||||
# ─── Normalize user/group databases ──────────────────────────────────────────
|
||||
# shadow's commonio_open() refuses to modify a database whose last line is not
|
||||
# newline-terminated, failing with a misleading "cannot open /etc/passwd".
|
||||
# Some installers/tools leave these files unterminated, which then breaks chsh,
|
||||
# usermod and groupadd alike — so make sure they end with a newline first.
|
||||
ensure_db_trailing_newlines() {
|
||||
local f
|
||||
for f in /etc/passwd /etc/group /etc/shadow; do
|
||||
[ -f "$f" ] || continue
|
||||
# `tail -c 1` yields the last byte; command substitution strips a
|
||||
# trailing newline, so non-empty output means the file is unterminated.
|
||||
if [ -n "$(psudo tail -c 1 "$f")" ]; then
|
||||
psudo sh -c "printf '\\n' >> '$f'"
|
||||
warn "Added missing trailing newline to $f (required by chsh/usermod)"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# ─── Main ─────────────────────────────────────────────────────────────────────
|
||||
main() {
|
||||
echo -e "${BOLD}${CYAN}"
|
||||
@@ -759,6 +780,7 @@ main() {
|
||||
|
||||
detect_os
|
||||
ensure_sudo
|
||||
ensure_db_trailing_newlines
|
||||
setup_passwordless_sudo
|
||||
|
||||
set_hostname
|
||||
|
||||
Reference in New Issue
Block a user