From 685224ccb20a40288d8aed6579ea0bbd6ca9e011 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 6 Jun 2026 01:37:51 +0200 Subject: [PATCH] fix(browser): guards chromium-por-udd dejan de auto-matchear el propio grep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug descubierto al ejecutar el reset real: los guards y los kills usaban 'pgrep -af [c]hromium | grep -F '. Como la ruta del user-data-dir contiene la cadena 'chromium' (~/.config/chromium-cdp), el propio proceso grep/ugrep —cuyo cmdline incluye — era capturado por pgrep, dando un falso positivo perpetuo: el guard creía siempre que había un chromium abierto y delete/restore abortaban con exit 2, y el lazo de cierre nunca convergía. Fix en delete_chrome_profile, restore_chrome_bookmarks, create_chrome_profile y el pipeline reset_chrome_profiles: enumerar por PID con 'pgrep -x chromium' (comm exactamente 'chromium', nunca grep/pgrep/bash) y leer /proc/PID/cmdline para comprobar el udd. Validado: reset destructivo real de los 4 perfiles completó OK, cada perfil quedó con solo uBlock + web_proxy y los bookmarks restaurados. --- .../browser/create_chrome_profile.sh | 15 ++++++++----- .../browser/delete_chrome_profile.sh | 15 ++++++++++--- .../browser/restore_chrome_bookmarks.sh | 13 ++++++++--- .../pipelines/reset_chrome_profiles.sh | 22 ++++++++++++++----- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/bash/functions/browser/create_chrome_profile.sh b/bash/functions/browser/create_chrome_profile.sh index 14268bf4..c9bccc08 100644 --- a/bash/functions/browser/create_chrome_profile.sh +++ b/bash/functions/browser/create_chrome_profile.sh @@ -204,18 +204,23 @@ EOF # este propio script porque filtramos por '[c]hromium'). systemctl --user kill -s SIGKILL "$_unit" 2>/dev/null || true systemctl --user stop "$_unit" 2>/dev/null || true - local _wait=0 _pids + # Matar por PID los procesos cuyo comm es exactamente "chromium" (pgrep -x) y cuyo cmdline + # contiene la ruta del udd. Usamos pgrep -x para NO auto-matchear grep/pgrep: el path del udd + # contiene la cadena "chromium" (~/.config/chromium-cdp). + local _wait=0 _p _pids while :; do - _pids=$(pgrep -af '[c]hromium' 2>/dev/null | grep -F -- "${_udd}" | awk '{print $1}') - [[ -z "$_pids" ]] && break + _pids="" + for _p in $(pgrep -x chromium 2>/dev/null); do + tr '\0' ' ' < "/proc/$_p/cmdline" 2>/dev/null | grep -qF -- "$_udd" && _pids="$_pids $_p" + done + [[ -z "${_pids// }" ]] && break # shellcheck disable=SC2086 kill -TERM $_pids 2>/dev/null || true sleep 0.5 (( _wait++ )) || true if [[ $_wait -ge 20 ]]; then - _pids=$(pgrep -af '[c]hromium' 2>/dev/null | grep -F -- "${_udd}" | awk '{print $1}') # shellcheck disable=SC2086 - [[ -n "$_pids" ]] && kill -9 $_pids 2>/dev/null || true + kill -9 $_pids 2>/dev/null || true break fi done diff --git a/bash/functions/browser/delete_chrome_profile.sh b/bash/functions/browser/delete_chrome_profile.sh index a3bc0f0a..bdd047c4 100644 --- a/bash/functions/browser/delete_chrome_profile.sh +++ b/bash/functions/browser/delete_chrome_profile.sh @@ -63,10 +63,19 @@ EOF fi # ── guard: ningún chromium debe tener ESTE user-data-dir abierto (excepto en dry-run) ── - # Por-udd, no global: permite operar sobre un user-data-dir de pruebas mientras el chromium - # diario (con otro --user-data-dir) sigue abierto. + # Por-udd, no global. Comprobamos por PID con comm=chromium (pgrep -x) y leemos su cmdline, + # para NO auto-matchear el propio `grep`/`pgrep` del pipe: como el path del udd contiene la + # cadena "chromium" (p.ej. ~/.config/chromium-cdp), un `pgrep -af '[c]hromium' | grep ` + # se detecta a sí mismo. pgrep -x chromium solo lista procesos cuyo nombre es exactamente + # "chromium" (el navegador), nunca grep/pgrep/bash. if [[ $_dry_run -eq 0 ]]; then - if pgrep -af '[c]hromium' 2>/dev/null | grep -qF -- "--user-data-dir=${_user_data_dir}"; then + local _p _busy=0 + for _p in $(pgrep -x chromium 2>/dev/null); do + if tr '\0' ' ' < "/proc/$_p/cmdline" 2>/dev/null | grep -qF -- "$_user_data_dir"; then + _busy=1; break + fi + done + if [[ $_busy -eq 1 ]]; then echo "delete_chrome_profile: hay un chromium con este user-data-dir abierto — ciérralo antes de borrar perfiles:" >&2 echo " pkill -TERM chromium" >&2 echo "(Chromium reescribe Local State desde memoria al cerrar y desharía el borrado)" >&2 diff --git a/bash/functions/browser/restore_chrome_bookmarks.sh b/bash/functions/browser/restore_chrome_bookmarks.sh index fc11ef2f..3f816408 100644 --- a/bash/functions/browser/restore_chrome_bookmarks.sh +++ b/bash/functions/browser/restore_chrome_bookmarks.sh @@ -62,10 +62,17 @@ EOF fi # ── guard: ningún chromium debe tener ESTE user-data-dir abierto (excepto en dry-run) ── - # Por-udd, no global: permite operar sobre un user-data-dir de pruebas mientras el chromium - # diario (con otro --user-data-dir) sigue abierto. + # Por-udd, no global. Comprobamos por PID con comm=chromium (pgrep -x) y leemos su cmdline, + # para NO auto-matchear el propio `grep`/`pgrep`: el path del udd contiene "chromium" + # (~/.config/chromium-cdp), así que un `pgrep -af '[c]hromium' | grep ` se detecta a sí mismo. if [[ $_dry_run -eq 0 ]]; then - if pgrep -af '[c]hromium' 2>/dev/null | grep -qF -- "--user-data-dir=${_user_data_dir}"; then + local _p _busy=0 + for _p in $(pgrep -x chromium 2>/dev/null); do + if tr '\0' ' ' < "/proc/$_p/cmdline" 2>/dev/null | grep -qF -- "$_user_data_dir"; then + _busy=1; break + fi + done + if [[ $_busy -eq 1 ]]; then echo "restore_chrome_bookmarks: hay un chromium con este user-data-dir abierto — ciérralo antes de restaurar:" >&2 echo " pkill -TERM chromium" >&2 echo "(Chromium reescribe Bookmarks desde memoria al cerrar y desharía la restauración)" >&2 diff --git a/bash/functions/pipelines/reset_chrome_profiles.sh b/bash/functions/pipelines/reset_chrome_profiles.sh index 0b9e7c51..5eb0fa4f 100644 --- a/bash/functions/pipelines/reset_chrome_profiles.sh +++ b/bash/functions/pipelines/reset_chrome_profiles.sh @@ -98,11 +98,23 @@ reset_chrome_profiles() { if [[ $_dry_run -eq 1 ]]; then echo " (dry-run: no se cierra nada)" else - if pgrep -af '[c]hromium' 2>/dev/null | grep -qF -- "--user-data-dir=${_udd}"; then - pkill -TERM -f -- "--user-data-dir=${_udd}" 2>/dev/null || true - local _i=0 - while pgrep -af '[c]hromium' 2>/dev/null | grep -qF -- "--user-data-dir=${_udd}"; do - _i=$((_i+1)); [[ $_i -ge 20 ]] && { pkill -9 -f -- "--user-data-dir=${_udd}" 2>/dev/null || true; break; } + # Por-PID con comm=chromium (pgrep -x) para no auto-matchear grep/pgrep (el path del udd + # contiene la cadena "chromium"). + local _p _kpids _i=0 + _kpids="" + for _p in $(pgrep -x chromium 2>/dev/null); do + tr '\0' ' ' < "/proc/$_p/cmdline" 2>/dev/null | grep -qF -- "$_udd" && _kpids="$_kpids $_p" + done + if [[ -n "${_kpids// }" ]]; then + # shellcheck disable=SC2086 + kill -TERM $_kpids 2>/dev/null || true + while :; do + _kpids="" + for _p in $(pgrep -x chromium 2>/dev/null); do + tr '\0' ' ' < "/proc/$_p/cmdline" 2>/dev/null | grep -qF -- "$_udd" && _kpids="$_kpids $_p" + done + [[ -z "${_kpids// }" ]] && break + _i=$((_i+1)); [[ $_i -ge 20 ]] && { kill -9 $_kpids 2>/dev/null || true; break; } sleep 0.5 done echo " chromium cerrado."