From 208d545e689602d195122eb18944ec302d1eb212 Mon Sep 17 00:00:00 2001 From: Sergio Date: Mon, 21 Sep 2026 19:11:08 +0000 Subject: [PATCH] =?UTF-8?q?sh:=20el=20trap=20del=20subshell,=20reportado?= =?UTF-8?q?=20=E2=80=94=20y=20la=20lecci=C3=B3n=20de=20que=20upstream=20ya?= =?UTF-8?q?=20lo=20ten=C3=ADa=20en=20sus=20PRUEBAS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit brush#1396 abierto. Antes de escribirlo apareció que reubeno/brush ya marcaba el fallo como known_failure en trap.yaml:226 (y :269, :323 para las otras dos variantes), sin issue que lo siguiera. Queda anotado porque es método, no anécdota: un known_failure en la suite del candidato es evidencia de primera y cuesta un gh api mirarla. Buscar en las PRUEBAS del candidato, no sólo en sus issues, antes de decir «hallazgo nuevo». Lo que el reporte sí aporta sobre esos TODOs: que las tres variantes son probablemente un mismo bug (on_exit() sólo lo llaman los puntos de entrada de nivel superior; el subshell de interp.rs:662-683 clona el shell y devuelve el exit code sin pasar por ahí), que también pega en pipeline y en segundo plano, y que falla en silencio con rc intacto. --- docs/plan-botar-busybox.md | 21 ++++++++++++++++++- .../sh-casos/08-trap-exit-y-estado.sh | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/plan-botar-busybox.md b/docs/plan-botar-busybox.md index bf15919d..7d45496c 100644 --- a/docs/plan-botar-busybox.md +++ b/docs/plan-botar-busybox.md @@ -542,7 +542,26 @@ El fixture `08-trap-exit-y-estado.sh` destapó algo que no estaba en el veredict **brush no ejecuta NUNCA el `trap … EXIT` de un subshell**, ni con `exit` explícito. Es independiente de #1394 y, a diferencia de aquél, **golpea el frente B**: un script de limpieza que confía en su trap no limpia, en silencio, con `rc=0`. La frase del veredicto —«en el producto brush no tiene -ninguna evidencia en contra»— ya no se sostiene: ahora la tiene. **Sin reportar upstream todavía.** +ninguna evidencia en contra»— ya no se sostiene: ahora la tiene. + +⚠ **Y upstream YA LO SABÍA — pero no como issue, sino dentro de su propia suite de compatibilidad**, +con el caso casi calcado al fixture y marcado `known_failure`: + +```yaml +# brush-shell/tests/cases/compat/builtins/trap.yaml:226 +- name: "subshell can set its own EXIT trap" + known_failure: true # TODO(traps): EXIT trap in subshell +``` + +Y no era uno sino tres TODOs para el mismo síntoma: `:226` subshell `( )`, `:269` sustitución de +comandos, `:323` sustitución de procesos. **Lección para el banco: un `known_failure` en la suite +ajena es evidencia de primera y cuesta un `gh api` mirarla — antes de escribir «hallazgo nuevo», +buscar en las PRUEBAS del candidato, no sólo en sus issues.** Lo nuestro seguía aportando: que las +tres variantes son probablemente un mismo bug (`on_exit()` sólo lo llaman los puntos de entrada de +nivel superior; el subshell de `interp.rs:662-683` clona el shell y devuelve el exit code sin +pasar por ahí), que también pega en pipeline y en segundo plano, y que es **silencioso**. + +**Reportado: [reubeno/brush#1396](https://github.com/reubeno/brush/issues/1396).** Y se confirmó la tercera, ya conocida: `shift` más allá de `$#` devuelve 2 (POSIX/busybox/bash: 1). diff --git a/scripts/fixtures/sh-casos/08-trap-exit-y-estado.sh b/scripts/fixtures/sh-casos/08-trap-exit-y-estado.sh index 1d1e37da..d93ff6b4 100644 --- a/scripts/fixtures/sh-casos/08-trap-exit-y-estado.sh +++ b/scripts/fixtures/sh-casos/08-trap-exit-y-estado.sh @@ -1,4 +1,6 @@ # `trap ... EXIT` + el estado de salida propagado: lo usan los scripts de la granja para limpiar. +# Destapó reubeno/brush#1396: brush NO ejecuta nunca el trap EXIT de un subshell, en silencio y con +# rc intacto. Upstream lo tenía marcado `known_failure` en trap.yaml:226 sin issue abierto. trap 'echo "trap-exit rc=$?"' EXIT ( trap 'echo "trap-subshell"' EXIT; true ) false