Files
fn_registry/bash/functions/shell/close_onlyoffice_instance.sh
T
egutierrez e1e9bb7499 feat(shell): auto-commit con 31 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-14 23:55:16 +02:00

110 lines
3.8 KiB
Bash

#!/usr/bin/env bash
# close_onlyoffice_instance — termina el/los proceso(s) DesktopEditors de una
# INSTANCIA AISLADA (slot) de ONLYOFFICE Desktop Editors, identificados por su
# HOME=/tmp/oo_<instance> en /proc/<pid>/environ. Opcionalmente limpia los
# directorios del slot con --purge.
#
# Funcion impura: lee /proc, envia señales a procesos y (con --purge) borra
# directorios bajo /tmp. NO toca la instancia personal del usuario: solo mata
# procesos cuyo HOME apunta al slot aislado.
#
# Slot aislado: cada instance usa HOME=/tmp/oo_<instance>,
# XDG_RUNTIME_DIR=/tmp/oo_<instance>_run, XDG_CONFIG_HOME=/tmp/oo_<instance>/.config.
# Sin -e: lecturas de /proc/<pid>/environ pueden fallar por carrera (el pid
# muere entre listar y leer); no deben abortar la funcion.
set -uo pipefail
close_onlyoffice_instance() {
local instance="demo"
local purge=false
# Parseo de args: [instance] y/o --purge en cualquier orden.
local a
for a in "$@"; do
case "$a" in
--purge) purge=true ;;
-*) echo "close_onlyoffice_instance: flag desconocido '$a'" >&2; return 2 ;;
*) instance="$a" ;;
esac
done
# 1. Dependencias del sistema (consistencia con el grupo, aunque aqui solo
# se usa /proc; onlyoffice/wmctrl/xdotool deben existir para operar el slot).
local dep
for dep in onlyoffice-desktopeditors wmctrl xdotool; do
if ! command -v "$dep" >/dev/null 2>&1; then
echo "close_onlyoffice_instance: falta dependencia '$dep'" >&2
return 1
fi
done
local oo_home="/tmp/oo_${instance}"
# 2. Encontrar pids de DesktopEditors con HOME=/tmp/oo_<instance>.
local pids=() pid environ
for pid in $(pgrep -f '/opt/onlyoffice/desktopeditors/DesktopEditors' 2>/dev/null || true); do
# Leer el entorno del proceso; saltar si no se puede (carrera/permisos).
environ=$(tr '\0' '\n' <"/proc/${pid}/environ" 2>/dev/null || true)
[[ -z "$environ" ]] && continue
if grep -qx "HOME=${oo_home}" <<<"$environ" 2>/dev/null; then
pids+=("$pid")
fi
done
# 3. Si no hay procesos del slot: not_running (purge opcional igualmente).
if [[ ${#pids[@]} -eq 0 ]]; then
local purged=false
if [[ "$purge" == true ]]; then
rm -rf -- /tmp/oo_"${instance}"* 2>/dev/null || true
purged=true
fi
printf '{"instance":"%s","killed_pids":[],"purged":%s,"status":"not_running"}\n' \
"$instance" "$purged"
return 0
fi
# 4. SIGTERM a todos los pids del slot.
kill -TERM "${pids[@]}" 2>/dev/null || true
# 5. Esperar ~3s a que mueran (NUNCA sleep foreground): read -t 0.3 x10.
local w=0 wmax=10
while [[ $w -lt $wmax ]]; do
local alive=false p
for p in "${pids[@]}"; do
if kill -0 "$p" 2>/dev/null; then alive=true; break; fi
done
[[ "$alive" == false ]] && break
read -t 0.3 _ </dev/null 2>/dev/null || true
w=$((w + 1))
done
# 6. SIGKILL a los que sigan vivos.
local p
for p in "${pids[@]}"; do
if kill -0 "$p" 2>/dev/null; then
kill -KILL "$p" 2>/dev/null || true
fi
done
# 7. Purge opcional de los dirs del slot.
local purged=false
if [[ "$purge" == true ]]; then
rm -rf -- /tmp/oo_"${instance}"* 2>/dev/null || true
purged=true
fi
# 8. JSON con el array de pids terminados.
local pids_json
pids_json=$(printf '%s,' "${pids[@]}")
pids_json="[${pids_json%,}]"
printf '{"instance":"%s","killed_pids":%s,"purged":%s,"status":"closed"}\n' \
"$instance" "$pids_json" "$purged"
return 0
}
# Ejecutable directo o sourceado.
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
close_onlyoffice_instance "$@"
fi