He leído muchas preguntas en varios sitios de intercambio de pila y foros de ayuda de Unix sobre cómo modificar las opciones de shell y luego restaurarlas. La más completa que encontré aquí es ¿Cómo "deshacer" un `set -x`?
La sabiduría recibida parece ser guardar el resultado de set +oo shopt -poy luego evalrestaurar la configuración anterior.
Sin embargo, en mis propias pruebas con bash 3.xy 4.x, la errexitopción no se guarda correctamente al realizar la sustitución de comandos.
Aquí hay un script de ejemplo para mostrar el problema:
set -o errexit
set -o nounset
echo "LOCAL SETTINGS:"
set +o
OLDOPTS=$(set +o)
echo
echo "SAVED SETTINGS:"
echo "$OLDOPTS"
Y salida (recorté algunas de las variables irrelevantes):
LOCAL SETTINGS:
set -o errexit
set -o nounset
SAVED SETTINGS:
set +o errexit
set -o nounset
Esto parece extremadamente peligroso. La mayoría de los scripts que escribo dependen errexitde detener la ejecución si alguno de los comandos falla. Acabo de localizar un error en uno de mis scripts causado por esto, donde la función que se suponía que debía restaurarse errexital final terminó anulándolo, volviéndolo al valor predeterminado de apagado durante la duración del script.
Lo que me gustaría poder hacer es escribir funciones que puedan configurar las opciones según sea necesario y luego restaurar todas las opciones correctamente antes de salir. Pero parece que en la subshell invocada por la sustitución del comando errexitno se hereda.
No sé cómo ahorrar el resultado set +osin utilizar la sustitución de comandos o saltar a través de los aros FIFO. Puedo leer, $SHELLOPTSpero no se puede escribir ni escribir en evalformato.
Sé que una alternativa es usar una función de subshell , pero eso introduce muchos dolores de cabeza para poder registrar la salida y transferir múltiples variables.
Probablemente relacionado: /programming/29532904/bash-subshell-errexit-semantics (parece que hay una solución para bash 4.4 y versiones posteriores, pero prefiero tener una solución portátil)

shoptopciones de bash set (como nullglob).Respuestas:
Lo que estás haciendo debería funcionar. Pero bash desactiva la
errexitopción en las sustituciones de comandos, por lo que conserva todas las opciones excepto esta. Esto es específico de bash y específico de laerrexitopción. Bash conservaerrexitcuando se ejecuta en modo POSIX. Desde bash 4.4, bash tampoco se borraerrexiten una sustitución de comando sishopt -s inherit_errexitestá vigente.Dado que la opción está desactivada antes de que se ejecute ningún código dentro de la sustitución del comando, debe verificarlo afuera.
Si no te gusta esta complejidad, usa zsh en su lugar.
fuente
bash4.4ahora tienelocal -(à laash) como equivalente azsh'ssetopt localoptions(o lo que ksh88 hace por defecto)shopt -s lastpipe; set +o | IFS= read -rd '' OLDOPTS || :(los dos conjuntos de opciones son otra debashlas idiosincrasias de).OLDOPTS="$(set +o); set -$-".Después de probar lo anterior en alpine 3.6, ahora he tomado el siguiente enfoque mucho más simple:
Según la documentación, "$ -" contiene la lista de opciones activas actualmente. Parece funcionar muy bien, ¿me estoy perdiendo algo?
fuente
set -uf)errexitse propaga en sustituciones de proceso.Cheque:
Versión bash:
fuente
La solución simple es agregar la
errexitconfiguración aOLDOPTS:Hecho.
fuente
[[ -o errexit ]](ksh / bash / zsh) y[ -o errexit ](bash / ksh / yash)shoptes un comando válido para bash, no hay una razón significativa para evitarlo (solo es una cuestión de su preferencia personal de cómo se deben escribir las respuestas). No es un cambio significativo. @ StéphaneChazelas