Improve script robustness and portability for logging, terminal execution, and uninstallation workflows.

This commit is contained in:
2025-09-20 08:53:18 +02:00
parent 608a6a371f
commit c46a1da405
2 changed files with 68 additions and 15 deletions

View File

@@ -7,8 +7,28 @@ LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/backtunnel"
[[ -d "$LOG_DIR" ]] || mkdir -p "$LOG_DIR" [[ -d "$LOG_DIR" ]] || mkdir -p "$LOG_DIR"
LOG_FILE="${LOG_DIR}/servicemenu.$(date +%Y%m%d-%H%M%S).log" LOG_FILE="${LOG_DIR}/servicemenu.$(date +%Y%m%d-%H%M%S).log"
# Simple rotation: keep the last 10 files # Simple rotation: keep the last 10 files (portable, avoids SC2207 and xargs -r)
ls -1t "$LOG_DIR"/servicemenu.*.log 2>/dev/null | awk 'NR>10{print}' | xargs -r rm -f shopt -s nullglob
logs=( "$LOG_DIR"/servicemenu.*.log )
if (( ${#logs[@]} > 10 )); then
pairs=()
for f in "${logs[@]}"; do
# Try GNU stat, then BSD stat; fall back to 0 if neither works
if mtime=$(stat -c %Y -- "$f" 2>/dev/null); then
:
elif mtime=$(stat -f %m -- "$f" 2>/dev/null); then
:
else
mtime=0
fi
pairs+=( "$mtime"$'\t'"$f" )
done
IFS=$'\n' read -r -d '' -a sorted < <(printf '%s\n' "${pairs[@]}" | sort -rn -k1,1 | cut -f2-; printf '\0')
for (( i=10; i<${#sorted[@]}; i++ )); do
rm -f -- "${sorted[i]}"
done
fi
shopt -u nullglob
cmd=( "$@" ) cmd=( "$@" )
{ {
@@ -34,13 +54,24 @@ cmd=( "$@" )
term="$(detect_term)" term="$(detect_term)"
echo "Chosen terminal: ${term:-<none>}"; echo echo "Chosen terminal: ${term:-<none>}"; echo
# Prebuild a shell-escaped command for bash -lc cases (preserves args)
shell_cmd=""
if (( ${#cmd[@]} )); then
printf -v shell_cmd '%q' "${cmd[0]}"
if (( ${#cmd[@]} > 1 )); then
for a in "${cmd[@]:1}"; do
printf -v shell_cmd '%s %q' "$shell_cmd" "$a"
done
fi
fi
# Run command in terminal (use hold/noclose if supported) # Run command in terminal (use hold/noclose if supported)
case "$term" in case "$term" in
konsole) exec konsole --noclose -e "${cmd[@]}" ;; konsole) exec konsole --noclose -e "${cmd[@]}" ;;
kitty) exec kitty -e "${cmd[@]}" ;; kitty) exec kitty -e "${cmd[@]}" ;;
alacritty) exec alacritty -e "${cmd[@]}" ;; alacritty) exec alacritty -e "${cmd[@]}" ;;
gnome-terminal) exec gnome-terminal -- bash -lc "exec \"${cmd[0]}\" ${cmd[@]:1}" ;; gnome-terminal) exec gnome-terminal -- bash -lc "exec $shell_cmd" ;;
kgx) exec kgx -- bash -lc "exec \"${cmd[0]}\" ${cmd[@]:1}" ;; # GNOME Console kgx) exec kgx -- bash -lc "exec $shell_cmd" ;; # GNOME Console
tilix) exec tilix -e "${cmd[@]}" ;; tilix) exec tilix -e "${cmd[@]}" ;;
xfce4-terminal) exec xfce4-terminal -e "${cmd[@]}" ;; xfce4-terminal) exec xfce4-terminal -e "${cmd[@]}" ;;
xterm) exec xterm -hold -e "${cmd[@]}" ;; xterm) exec xterm -hold -e "${cmd[@]}" ;;

View File

@@ -16,6 +16,22 @@ SHARE_DIR="$DESTDIR$PREFIX/share/backtunnel"
ETC_DIR="$DESTDIR/etc/backtunnel" ETC_DIR="$DESTDIR/etc/backtunnel"
say() { printf '[BackTunnel] %s\n' "$*"; } say() { printf '[BackTunnel] %s\n' "$*"; }
say_warn() { printf '[BackTunnel] WARN: %s\n' "$*" >&2; }
# Portable directory prune: remove dir if empty, then move up until stop boundary
prune_dir() {
local dir="${1%/}"
local stop="${2%/}"
while [[ -n "$dir" && "$dir" != "/" && "$dir" != "$stop" ]]; do
rmdir "$dir" 2>/dev/null || break
dir="$(dirname "$dir")"
done
}
# Friendly notice if uninstalling the live system without root
if [[ -z "$DESTDIR" && ${EUID:-$(id -u)} -ne 0 ]]; then
say_warn "Running without root; some files may not be removed due to permissions."
fi
say "Uninstalling from PREFIX=${PREFIX} DESTDIR=${DESTDIR} (PURGE=${PURGE})" say "Uninstalling from PREFIX=${PREFIX} DESTDIR=${DESTDIR} (PURGE=${PURGE})"
@@ -27,6 +43,8 @@ rm -f "$BINDIR/backtunnel-share" \
"$BINDIR/backtunnel-open-term" \ "$BINDIR/backtunnel-open-term" \
"$BINDIR/backtunnel-share-tui" \ "$BINDIR/backtunnel-share-tui" \
"$BINDIR/backtunnel-access-tui" "$BINDIR/backtunnel-access-tui"
# Optionally remove helper that may be present on some installs
rm -f "$BINDIR/backtunnel-init"
# --- Man page --- # --- Man page ---
rm -f "$MANDIR/backtunnel.1" rm -f "$MANDIR/backtunnel.1"
@@ -42,28 +60,32 @@ rm -f "$KIO_SM/backtunnel_share.desktop" \
"$KSVC5/backtunnel_access.desktop" "$KSVC5/backtunnel_access.desktop"
# --- Optional desktop launcher --- # --- Optional desktop launcher ---
rm -f "$APPDIR/backtunnel.desktop" || true rm -f "$APPDIR/backtunnel.desktop"
# --- Shared defaults (only if PURGE=1) --- # --- Shared defaults (only if PURGE=1) ---
if [[ "$PURGE" = "1" ]]; then if [[ "$PURGE" = "1" ]]; then
say "Purging shared defaults under $SHARE_DIR and $ETC_DIR" say "Purging shared defaults under $SHARE_DIR and $ETC_DIR"
rm -f "$SHARE_DIR/profiles.ini" 2>/dev/null || true rm -f "$SHARE_DIR/profiles.ini" 2>/dev/null || true
rm -f "$ETC_DIR/profiles.ini" 2>/dev/null || true rm -f "$ETC_DIR/profiles.ini" 2>/dev/null || true
# Remove directories if empty (and prune empty parents) # Remove directories if empty (and prune empty parents up to safe boundaries)
rmdir -p --ignore-fail-on-non-empty "$SHARE_DIR" 2>/dev/null || true prune_dir "$SHARE_DIR" "$DESTDIR$PREFIX/share"
rmdir -p --ignore-fail-on-non-empty "$ETC_DIR" 2>/dev/null || true prune_dir "$ETC_DIR" "$DESTDIR/etc"
else else
# Optionally clean up empty share dir if package manager removed files already # Optionally clean up empty share dir if package manager removed files already
rmdir -p --ignore-fail-on-non-empty "$SHARE_DIR" 2>/dev/null || true prune_dir "$SHARE_DIR" "$DESTDIR$PREFIX/share"
say "Keeping shared defaults: $SHARE_DIR/ and $ETC_DIR/ (set PURGE=1 to remove)" say "Keeping shared defaults: $SHARE_DIR/ and $ETC_DIR/ (set PURGE=1 to remove)"
fi fi
# --- Refresh desktop/KDE cache (best-effort) --- # --- Refresh desktop/KDE cache (best-effort, skip during packaging) ---
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database -q || true if [[ -z "$DESTDIR" ]]; then
if command -v kbuildsycoca6 >/dev/null 2>&1; then if command -v update-desktop-database >/dev/null 2>&1; then
kbuildsycoca6 --noincremental >/dev/null 2>&1 || true update-desktop-database -q || true
elif command -v kbuildsycoca5 >/dev/null 2>&1; then fi
kbuildsycoca5 --noincremental >/dev/null 2>&1 || true if command -v kbuildsycoca6 >/dev/null 2>&1; then
kbuildsycoca6 --noincremental >/dev/null 2>&1 || true
elif command -v kbuildsycoca5 >/dev/null 2>&1; then
kbuildsycoca5 --noincremental >/dev/null 2>&1 || true
fi
fi fi
say "Uninstall complete." say "Uninstall complete."