Files
takana/scripts/fixtures/sh-casos/08-trap-exit-y-estado.sh
T
Sergio 6809ef4be2 simi: el /bin/sh propio del producto — 4448 líneas, sólo libc, y CERO divergencias contra el ash
«simi» es boca/lengua en quechua. Es el sh que el frente C necesitaba: busybox
está en la raíz de confianza del arranque (STAGE1_COMPONENTS, ATTEST_PATHS) y en
el exec de cada card, y el candidato ajeno que se midió —brush 0.4.0— pesa 6,9 MB,
arranca 4x más lento que el ash y trae dos divergencias medidas (#1394, #1396).

Alcance MEDIDO, no supuesto: las 23 cards con shell (8 builtins, 13
construcciones), los 21 /init empotrados de las imágenes (+ if, funciones, case,
aquí-documentos) y el POSIX de takana-live-install.sh.

Resultado del banco diferencial, 159 casos contra el ash de busybox 1.36.1
(10 fixtures de regresión, 107 de tortura de comillas, 23 fragmentos de cards,
19 /init empotrados):

    simi   DIVERGE=0        bash  DIVERGE=8        brush  DIVERGE=35

Incluye el bucle REAL de config.status que genera cualquier configure de
autotools — el que tumbó a brush. 499 KB release, 1,4x la latencia del ash
(brush: 4,1x). 47 pruebas propias en verde.

Seis bugs que el banco destapó, y ninguno se veía sin un control al lado:

1. El lexer fundía lo entrecomillado con lo desnudo, así que x="a b" se ejecutaba
   como ORDEN y el error decía «no encontrado» — mandando a buscar al lugar
   equivocado. Ahora el comillado es por carácter.
2. Usaba la barra invertida como marca interna y la quitaba al final, así que una
   barra PRODUCIDA por una sustitución se perdía. La quita de comillas es sobre
   las comillas de la palabra, nunca sobre el resultado de una expansión: hace
   falta una máscara de protección, no un escape dentro del texto.
3. set -e no se suspendía dentro del cuerpo de una función llamada desde una
   condición. Ahora es un contador dinámico, que entra solo donde corresponde.
4. Los delimitadores de la sustitución de orden y de ${ } no respetaban la barra
   invertida: un paréntesis escapado cerraba la sustitución.
5. Las clases entre corchetes no entendían la barra invertida — y la del
   config.status de libtool es literalmente una clase con cuatro escapes.
6. Dentro de comillas dobles el cuerpo de un backtick sigue entre comillas, así
   que la barra también se elimina ante la comilla doble.

Y uno que el banco NO vio y sí vio la prueba de regresión: el trap EXIT HEREDADO
se disparaba en el subshell. POSIX §2.12 manda resetearlo — es la mitad
complementaria del #1396 de brush, y al revés. Los dos oráculos hacen falta; el
caso quedó agregado al fixture 08.
2026-09-21 20:22:40 +00:00

13 lines
791 B
Bash

# `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
echo "ultimo=$?"
( trap 'echo "[heredado-no-debe-sonar]"' EXIT; true ) >/dev/null 2>&1
# Y la otra mitad, que es la que POSIX §2.12 manda al revés: el trap HEREDADO se resetea al entrar
# al subshell, así que el de arriba NO tiene que sonar acá. simi lo tenía mal en su primera versión
# —lo disparaba— y el banco no lo veía porque ningún caso lo probaba. Ahora sí.
( echo "subshell sin trap propio" )