#!/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_ en /proc//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_, # XDG_RUNTIME_DIR=/tmp/oo__run, XDG_CONFIG_HOME=/tmp/oo_/.config. # Sin -e: lecturas de /proc//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_. 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 || 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