2025-09-19 15:30:41 +02:00
|
|
|
#!/usr/bin/env bash
|
2025-09-21 09:45:43 +02:00
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
# Copyright (c) 2025 LUXIM d.o.o., Slovenia
|
|
|
|
|
# Author: Matjaž Mozetič
|
|
|
|
|
#
|
|
|
|
|
# Name: backtunnel-open-term
|
|
|
|
|
# Summary: Open a command in the user's available terminal emulator, with logging and simple rotation.
|
|
|
|
|
# Description:
|
|
|
|
|
# Detects an installed terminal emulator (preferring Konsole on KDE sessions), opens it,
|
|
|
|
|
# and executes the provided command with arguments. Logs session metadata and output to
|
|
|
|
|
# ${XDG_STATE_HOME:-$HOME/.local/state}/backtunnel/servicemenu.<timestamp>.log, keeping the
|
|
|
|
|
# last 10 logs with a portable rotation routine.
|
|
|
|
|
#
|
|
|
|
|
# Usage:
|
|
|
|
|
# backtunnel-open-term <cmd> [args...]
|
|
|
|
|
#
|
|
|
|
|
# Examples:
|
|
|
|
|
# backtunnel-open-term backtunnel-access-tui "/path/to/dir"
|
|
|
|
|
# backtunnel-open-term bash -lc 'echo Hello'
|
|
|
|
|
#
|
|
|
|
|
# Dependencies:
|
|
|
|
|
# - bash
|
|
|
|
|
# - A terminal emulator (one of: konsole, kitty, alacritty, gnome-terminal, kgx, tilix, xfce4-terminal, xterm)
|
|
|
|
|
# - stat, sort, cut, date (coreutils-compatible)
|
|
|
|
|
#
|
|
|
|
|
# Exit codes:
|
|
|
|
|
# 0 started successfully (or backgrounded if no terminal is available)
|
|
|
|
|
# 1+ invalid usage or failures during setup/execution
|
|
|
|
|
#
|
|
|
|
|
# Notes:
|
|
|
|
|
# - If no terminal emulator is found, the command is started in the background via nohup
|
|
|
|
|
# and the log path is printed.
|
|
|
|
|
# - Uses exec for supported terminals to replace the current process; otherwise prints info then exits.
|
2025-09-19 15:30:41 +02:00
|
|
|
set -euo pipefail
|
2025-09-21 09:45:43 +02:00
|
|
|
# ... existing code ...
|
2025-09-19 15:30:41 +02:00
|
|
|
LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/backtunnel"
|
|
|
|
|
[[ -d "$LOG_DIR" ]] || mkdir -p "$LOG_DIR"
|
|
|
|
|
LOG_FILE="${LOG_DIR}/servicemenu.$(date +%Y%m%d-%H%M%S).log"
|
|
|
|
|
|
2025-09-20 08:53:18 +02:00
|
|
|
# Simple rotation: keep the last 10 files (portable, avoids SC2207 and xargs -r)
|
2025-09-21 09:45:43 +02:00
|
|
|
# Purpose: remove older log files while remaining compatible across GNU/BSD userlands.
|
2025-09-20 08:53:18 +02:00
|
|
|
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
|
2025-09-19 15:30:41 +02:00
|
|
|
|
|
|
|
|
cmd=( "$@" )
|
|
|
|
|
{
|
|
|
|
|
echo "=== BackTunnel servicemenu ==="
|
|
|
|
|
echo "Time: $(date -Is)"
|
|
|
|
|
echo "PWD: $(pwd)"
|
|
|
|
|
echo "User: $(id -un) (uid=$(id -u))"
|
|
|
|
|
echo "Cmd: ${cmd[*]}"
|
|
|
|
|
echo "Env: BACKTUNNEL_DEBUG=${BACKTUNNEL_DEBUG:-} SHELL=${SHELL:-} DISPLAY=${DISPLAY:-}"
|
|
|
|
|
echo
|
|
|
|
|
|
2025-09-21 09:45:43 +02:00
|
|
|
# detect_term: choose a terminal emulator to launch the command
|
|
|
|
|
# Output: prints the chosen terminal name or empty string if none found.
|
|
|
|
|
# Prefers Konsole when KDE session is detected.
|
2025-09-19 15:30:41 +02:00
|
|
|
detect_term() {
|
|
|
|
|
if [[ -n "${KDE_FULL_SESSION:-}" ]] && command -v konsole >/dev/null 2>&1; then
|
|
|
|
|
echo "konsole"; return
|
|
|
|
|
fi
|
2025-09-21 18:56:15 +02:00
|
|
|
# Prefer widely used modern terminals first when not on KDE
|
|
|
|
|
for t in wezterm kitty alacritty kgx gnome-terminal tilix xfce4-terminal konsole xterm; do
|
2025-09-19 15:30:41 +02:00
|
|
|
if command -v "$t" >/dev/null 2>&1; then echo "$t"; return; fi
|
|
|
|
|
done
|
|
|
|
|
echo "" # none
|
|
|
|
|
}
|
2025-09-21 09:45:43 +02:00
|
|
|
# ... existing code ...
|
2025-09-19 15:30:41 +02:00
|
|
|
term="$(detect_term)"
|
|
|
|
|
echo "Chosen terminal: ${term:-<none>}"; echo
|
|
|
|
|
|
2025-09-20 08:53:18 +02:00
|
|
|
# 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
|
|
|
|
|
|
2025-09-19 15:30:41 +02:00
|
|
|
# Run command in terminal (use hold/noclose if supported)
|
|
|
|
|
case "$term" in
|
|
|
|
|
konsole) exec konsole --noclose -e "${cmd[@]}" ;;
|
2025-09-21 18:56:15 +02:00
|
|
|
wezterm) exec wezterm start -- "${cmd[@]}" ;;
|
2025-09-19 15:30:41 +02:00
|
|
|
kitty) exec kitty -e "${cmd[@]}" ;;
|
|
|
|
|
alacritty) exec alacritty -e "${cmd[@]}" ;;
|
2025-09-20 08:53:18 +02:00
|
|
|
gnome-terminal) exec gnome-terminal -- bash -lc "exec $shell_cmd" ;;
|
|
|
|
|
kgx) exec kgx -- bash -lc "exec $shell_cmd" ;; # GNOME Console
|
2025-09-19 15:30:41 +02:00
|
|
|
tilix) exec tilix -e "${cmd[@]}" ;;
|
|
|
|
|
xfce4-terminal) exec xfce4-terminal -e "${cmd[@]}" ;;
|
|
|
|
|
xterm) exec xterm -hold -e "${cmd[@]}" ;;
|
|
|
|
|
*)
|
|
|
|
|
echo "No terminal emulator found. Running in background (nohup)."
|
|
|
|
|
nohup "${cmd[@]}" >/dev/null 2>&1 &
|
|
|
|
|
echo "Started in background (pid=$!)."
|
|
|
|
|
echo "Log: $LOG_FILE"
|
|
|
|
|
exit 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
} | tee -a "$LOG_FILE"
|