e1e9bb7499
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
110 lines
3.8 KiB
Bash
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
|