Esta pregunta apareció en un cuestionario previo a la entrevista y me está volviendo loco. ¿Alguien puede responder esto y tranquilizarme? La prueba no tiene referencia a un shell en particular, pero la descripción del trabajo es para un sa de Unix. de nuevo la pregunta es simplemente ...
¿Qué hace 'set -e' y por qué podría considerarse peligroso?
Respuestas:
set -e
hace que el shell salga si algún subcomando o tubería devuelve un estado distinto de cero.La respuesta que probablemente estaba buscando el entrevistador es:
De http://www.debian.org/doc/debian-policy/ch-opersys.html 9.3.2 -
Esta es una pregunta válida desde el punto de vista del entrevistador porque evalúa a los candidatos con conocimientos prácticos de scripting y automatización a nivel de servidor
fuente
De
bash(1)
:Desafortunadamente, no soy lo suficientemente creativo como para pensar por qué sería peligroso, aparte de "el resto del script no se ejecutará" o "posiblemente podría enmascarar problemas reales".
fuente
set
! Siempre termino enbuiltin(1)
. Gracias.set
debe ser encontradaman 1 bash
? y ¿cómo podría alguien encontrar la-e
opción para laset
palabra clave en una página de manual que es tan enorme? no puedes/-e
buscar aquíhelp set
Cabe señalar que
set -e
se puede activar y desactivar para varias secciones de un script. No tiene que estar activado para la ejecución de todo el script. Incluso podría habilitarse condicionalmente. Dicho esto, nunca lo uso ya que hago mi propio manejo de errores (o no).También es digno de mención esto de la sección de la página del manual de Bash en el
trap
comando que también describe cómoset -e
funciona bajo ciertas circunstancias.Entonces, hay algunas condiciones bajo las cuales un estado distinto de cero no causará una salida.
Creo que el peligro está en no entender cuándo
set -e
entra en juego y cuándo no, y confiar en él incorrectamente bajo alguna suposición inválida.Consulte también BashFAQ / 105 ¿Por qué set -e (o set -o errexit, o trap ERR) no hacen lo que esperaba?
fuente
Tenga en cuenta que este es un cuestionario para una entrevista de trabajo. Las preguntas pueden haber sido escritas por el personal actual y pueden estar equivocadas. Esto no es necesariamente malo, y todos cometen errores, y las preguntas de la entrevista a menudo se quedan en un rincón oscuro sin revisión, y solo salen durante una entrevista.
Es completamente posible que 'set -e' no haga nada que consideremos "peligroso". Pero el autor de esa pregunta puede creer erróneamente que 'set -e' es peligroso, debido a su propia ignorancia o parcialidad. Tal vez escribieron un script de shell con errores, bombardearon horriblemente, y erróneamente pensaron que 'culpable era' set -e ', cuando de hecho se negaron a escribir la verificación de errores adecuada.
He participado en probablemente 40 entrevistas de trabajo en los últimos 2 años, y los entrevistadores a veces hacen preguntas que están mal o tienen respuestas que están mal.
O tal vez es una pregunta capciosa, que sería poco convincente, pero no del todo inesperada.
O tal vez esta sea una buena explicación: http://www.mail-archive.com/[email protected]/msg473314.html
fuente
set -e
le dice a bash, en un script, que salga siempre que algo devuelva un valor de retorno distinto de cero.Pude ver cómo sería molesto y con errores, no estoy seguro acerca de peligroso, a menos que haya abierto los permisos sobre algo, y antes de que pudiera restringirlos nuevamente, su script murió.
fuente
set -e
, de hecho, para mí habla de pereza para ignorar la comprobación de errores en sus scripts ... así que tenga esto en cuenta, también con este empleador ... si lo usan mucho, cómo son sus guiones, que inevitablemente tendrá que mantener ...set -e
finaliza el script si se encuentra un código de salida distinto de cero, excepto bajo ciertas condiciones. Para resumir los peligros de su uso en pocas palabras: no se comporta como la gente piensa que lo hace.En mi opinión, debe considerarse como un hack peligroso que continúa existiendo solo con fines de compatibilidad. La
set -e
declaración no convierte el shell de un lenguaje que usa códigos de error en un lenguaje que usa un flujo de control similar a una excepción, simplemente intenta mal emular ese comportamiento.Greg Wooledge tiene mucho que decir sobre los peligros de
set -e
:set -e
)En el segundo enlace, hay varios ejemplos del comportamiento poco intuitivo e impredecible de
set -e
.Algunos ejemplos del comportamiento poco intuitivo de
set -e
(algunos tomados del enlace wiki anterior):let x++
devuelve 0, que lalet
palabra clave trata como un valor falso y se convierte en un código de salida distinto de cero.set -e
se da cuenta de esto y termina silenciosamente el script.Lo anterior funciona como se esperaba, imprimiendo una advertencia si
/opt/foo
ya existe.Lo anterior, a pesar de que la única diferencia es que una sola línea se ha refactorizado en una función, finalizará si
/opt/foo
no existe. Esto se debe a que el hecho de que funcionó originalmente es una excepción especial alset -e
comportamiento de. Cuandoa && b
devuelve un valor distinto de cero, es ignorado porset -e
. Sin embargo, ahora que es una función, el código de salida de la función es igual al código de salida de ese comando, y la función que devuelve un valor distinto de cero terminará silenciosamente el script.Lo anterior leerá la matriz
config_vars
del archivoconfig
. Como el autor podría pretender, termina con un error siconfig
falta. Como el autor podría no tener la intención, termina silenciosamente siconfig
no termina en una nueva línea. Siset -e
no se usara aquí,config_vars
contendría todas las líneas del archivo, ya sea que terminara o no en una nueva línea.Los usuarios de Sublime Text (y otros editores de texto que manejan líneas nuevas incorrectamente), tengan cuidado.
El autor aquí podría esperar razonablemente que si por alguna razón el usuario
$user
no existe, elgroups
comando fallará y el script terminará en lugar de permitir que el usuario realice alguna tarea sin auditar. Sin embargo, en este caso laset -e
terminación nunca surte efecto. Si$user
no se puede encontrar por alguna razón, en lugar de terminar el script, lashould_audit_user
función simplemente devolverá datos incorrectos como siset -e
no estuvieran vigentes.Esto se aplica a cualquier función invocada desde la parte de condición de una
if
declaración, sin importar cuán profundamente anidada, sin importar dónde esté definida, sin importar si se ejecutaset -e
dentro de ella nuevamente. El usoif
en cualquier punto deshabilita completamente el efectoset -e
hasta que el bloque de condición se ejecute completamente. Si el autor no es consciente de esta trampa, o no conoce toda su pila de llamadas en todas las situaciones posibles en las que se puede invocar una función, entonces escribirán un código defectuoso y la falsa sensación de seguridad proporcionadaset -e
será al menos parcialmente culpa.Incluso si el autor es plenamente consciente de este escollo, la solución consiste en escribir el código de la misma manera en que se escribiría sin él
set -e
, haciendo que ese interruptor sea menos que inútil; el autor no solo tiene que escribir el código de manejo manual de errores como siset -e
no estuviera vigente, sino que la presencia de losset -e
puede haber engañado haciéndoles creer que no tienen que hacerlo.Algunos inconvenientes adicionales de
set -e
:let x++
anteriores, este no es el caso. Si el script muere inesperadamente, generalmente es silencioso, lo que dificulta la depuración. Si el script no muere y esperaba que lo hiciera (vea el punto anterior), entonces tiene un error más sutil e insidioso en sus manos.if
viñeta de condición.set -e
haber sido modificado entre esas versiones.set -e
es un tema polémico, y algunas personas conscientes de los problemas que lo rodean recomiendan no hacerlo, mientras que otros simplemente recomiendan tener cuidado mientras están activos para conocer las trampas. Hay muchos novatos de scripting de shell que recomiendanset -e
en todos los scripts como un todo para condiciones de error, pero en la vida real no funciona de esa manera.set -e
No es un sustituto de la educación.fuente
Diría que es peligroso porque ya no controlas el flujo de tu guión. El script puede finalizar siempre que cualquiera de los comandos que invoca devuelva un valor distinto de cero. Entonces, todo lo que tiene que hacer es hacer algo que altere el comportamiento o la salida de cualquiera de los componentes, y puede terminar el script principal. Puede ser más un problema de estilo, pero definitivamente tiene consecuencias. ¿Qué pasaría si ese script principal tuyo supusiera establecer alguna bandera, y no lo hizo porque terminó antes? Terminaría fallando el resto del sistema si supone que la bandera debería estar allí, o trabajando con un valor predeterminado o antiguo inesperado.
fuente
Como un ejemplo más concreto de la respuesta de @ Marcin que personalmente me ha mordido, imagine que hay una
rm foo/bar.txt
línea en algún lugar de su guión. Por lo general, no es gran cosa si enfoo/bar.txt
realidad no existe. Sin embargo, conset -e
presente ahora, su secuencia de comandos terminará temprano allí Upsfuente