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 -ehace 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.setdebe ser encontradaman 1 bash? y ¿cómo podría alguien encontrar la-eopción para lasetpalabra clave en una página de manual que es tan enorme? no puedes/-ebuscar aquíhelp setCabe señalar que
set -ese 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
trapcomando que también describe cómoset -efunciona 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 -eentra 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 -ele 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 -efinaliza 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 -edeclaració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 laletpalabra clave trata como un valor falso y se convierte en un código de salida distinto de cero.set -ese da cuenta de esto y termina silenciosamente el script.Lo anterior funciona como se esperaba, imprimiendo una advertencia si
/opt/fooya existe.conjunto -e check_previous_install () { [-d / opt / foo] && echo "Advertencia: foo ya está instalado. Se sobrescribirá". > Y 2 } check_previous_install echo "Instalando foo ..."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/foono existe. Esto se debe a que el hecho de que funcionó originalmente es una excepción especial alset -ecomportamiento de. Cuandoa && bdevuelve 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_varsdel archivoconfig. Como el autor podría pretender, termina con un error siconfigfalta. Como el autor podría no tener la intención, termina silenciosamente siconfigno termina en una nueva línea. Siset -eno se usara aquí,config_varscontendrí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.
conjunto -e should_audit_user () { grupos de grupos locales = "$ (grupos" $ 1 ")" para grupo en $ grupos; hacer si ["$ grupo" = auditoría]; luego devuelve 0; fi hecho volver 1 } if should_audit_user "$ usuario"; entonces registrador 'Blah' fiEl autor aquí podría esperar razonablemente que si por alguna razón el usuario
$userno existe, elgroupscomando fallará y el script terminará en lugar de permitir que el usuario realice alguna tarea sin auditar. Sin embargo, en este caso laset -eterminación nunca surte efecto. Si$userno se puede encontrar por alguna razón, en lugar de terminar el script, lashould_audit_userfunción simplemente devolverá datos incorrectos como siset -eno estuvieran vigentes.Esto se aplica a cualquier función invocada desde la parte de condición de una
ifdeclaración, sin importar cuán profundamente anidada, sin importar dónde esté definida, sin importar si se ejecutaset -edentro de ella nuevamente. El usoifen cualquier punto deshabilita completamente el efectoset -ehasta 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 -eserá 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 -eno estuviera vigente, sino que la presencia de losset -epuede 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.ifviñeta de condición.set -ehaber sido modificado entre esas versiones.set -ees 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 -een todos los scripts como un todo para condiciones de error, pero en la vida real no funciona de esa manera.set -eNo 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.txtlínea en algún lugar de su guión. Por lo general, no es gran cosa si enfoo/bar.txtrealidad no existe. Sin embargo, conset -epresente ahora, su secuencia de comandos terminará temprano allí Upsfuente