From ece4ac273572094239fb1ad6e57c5a4bcee9cce1 Mon Sep 17 00:00:00 2001 From: John Coffey Date: Sat, 22 Aug 2026 22:39:35 -0700 Subject: [PATCH] Don't require root to print usage Both `mkdir -p "$LOG_DIR"` and `exec > >(tee -a "$LOG_FILE")` ran at file scope, before a single argument was parsed. On any machine where /var/log is not writable by the caller -- which is every machine, since this needs sudo -- `--help` and a mistyped flag both failed with a raw mkdir or tee error rather than printing usage or naming the bad flag. Both now happen in ensure_log_dir(), called from main() once a real command has been dispatched, so usage and argument errors work for anyone while everything from the command onward is still logged. exec applies to the shell rather than the function, so moving it changes nothing about what gets captured -- verified by running a command with the log directory redirected and confirming the output landed in it. A non-root command now also fails with "Cannot create /var/log/... -- re-run with sudo" instead of leaking mkdir's own message. --- ubuntu-to-mint-convert-v3.sh | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ubuntu-to-mint-convert-v3.sh b/ubuntu-to-mint-convert-v3.sh index ea6c4db..07c5fbe 100644 --- a/ubuntu-to-mint-convert-v3.sh +++ b/ubuntu-to-mint-convert-v3.sh @@ -53,9 +53,15 @@ SCRIPT_VERSION="5.1" # Globals / Defaults # ========================= LOG_DIR="/var/log/ubuntu-to-mint" -mkdir -p "$LOG_DIR" +# Deliberately NOT created here. This runs at file scope, before any +# argument is parsed, so creating it meant `--help` and a mistyped flag +# both died with "mkdir: Permission denied" instead of printing usage. +# ensure_log_dir is called once a real command has been dispatched. LOG_FILE="${LOG_DIR}/ubuntu-to-mint-$(date +%Y%m%d-%H%M%S).log" -exec > >(tee -a "$LOG_FILE") 2>&1 +# Logging is started by ensure_log_dir once a command has been dispatched, +# for the same reason the directory is not created here: at file scope this +# ran before argument parsing, so `--help` tried to tee into a directory +# that does not exist and may not be creatable. # CLI defaults CMD="" @@ -1158,10 +1164,21 @@ parse_args_any_order() { # ========================= # Main # ========================= +ensure_log_dir() { + mkdir -p "$LOG_DIR" 2>/dev/null || \ + die "Cannot create ${LOG_DIR}. Every command here needs root -- re-run with sudo." + # exec applies to the shell, not just this function, so everything from + # here on is both shown and logged. + exec > >(tee -a "$LOG_FILE") 2>&1 +} + main() { parse_args_any_order "$@" [[ -n "$CMD" ]] || { usage; exit 1; } + # Past this point a command was named, so the log directory is wanted. + ensure_log_dir + case "$CMD" in doctor) doctor ;; plan) plan_mode ;;