¿Por qué Bash no pasa la opción errexit para ordenar sustituciones?

¿Por qué Bash no pasa la opción errexit para ordenar sustituciones?

Opciones de shell establecidas porsetincorporadose heredan en subcapas (al menos errexit). Esto se puede probar mediante:

set -o errexit

function foo() {
    echo "foo:$BASHPID"
    false
    echo 'after' 
}

echo "main:$BASHPID"
( foo )

Sin embargo, las opciones no parecen heredadas ensustitución de comando, que también deberían ser subcapas según la documentación de Bash. Prueba:

set -o errexit

function foo() {
    echo "foo:$BASHPID"
    false
    echo 'after' 
}

echo "main:$BASHPID"
output=$(foo)
echo "output: $output"

Rendimiento esperado:

main:123
output: foo:124

Salida real:

main:123
output: foo:124
after

¿Es eso esperado o es un error?

Respuesta1

Sí, se espera que, cuando no esté en modo POSIX (como cuando se ejecuta como sh), bash se restablezca errexitdentro de las sustituciones de comandos de forma predeterminada.

Si desea errexitconservarse dentro de las sustituciones de comandos, con bash 4.4 o posterior, use:

inherit_errexit

Si se establece, la sustitución de comandos hereda el valor de la errexitopción, en lugar de desactivarlo en el entorno del subshell. Esta opción está habilitada cuando el modo POSIX está habilitado.

(Demanual de bash.)Otra parte de la documentación.lo hizo más explícito:

Habilitar el modo POSIX tiene el efecto de configurar la inherit_errexitopción, por lo que los subshells generados para ejecutar sustituciones de comandos heredan el valor de la -eopción del shell principal.Cuando la inherit_errexitopción no está habilitada, Bash la borra -een dichos subniveles.

Para verificar:

$ bash -o errexit -c 'echo "$(echo "$SHELLOPTS")"'
braceexpand:hashall:interactive-comments
$ bash -o errexit -O inherit_errexit -c 'echo "$(echo "$SHELLOPTS")"'
braceexpand:errexit:hashall:interactive-comments

En bash 4.2 y versiones anteriores, errexitse mostraba en la versión anterior, pero aún estaba efectivamente deshabilitado:

$ bash-4.2 -o errexit c 'echo "$(false; echo "$SHELLOPTS")"'
braceexpand:errexit:hashall:interactive-comments
$ bash-4.2 -o posix -o errexit -c 'echo "<$(false; echo "$SHELLOPTS")> $?"'
<> 1

información relacionada