He notado que muchos scripts entrypoint.sh para Docker hacen algo como esto:
#!/bin/bash
set -e
... code ...
exec "[email protected]"
¿Para qué son set -e
y exec "[email protected]"
para qué?
He notado que muchos scripts entrypoint.sh para Docker hacen algo como esto:
#!/bin/bash
set -e
... code ...
exec "[email protected]"
¿Para qué son set -e
y exec "[email protected]"
para qué?
set -e
se considera mucho más propenso a errores que el manejo de errores escritos a mano. (Si tiene prisa, omita la analogía en la parte superior de los ejercicios a continuación).Respuestas:
Básicamente, toma los argumentos de la línea de comandos que se le pasan
entrypoint.sh
y los ejecuta como un comando. La intención es básicamente "Hacer todo en este script .sh, luego en el mismo shell ejecutar el comando que el usuario pasa en la línea de comandos".Ver:
fuente
exec "[email protected]"
reemplazará el proceso actualmente en ejecución con el nuevo proceso generado para los argumentos pasados. Importante para la señalización de Docker: stackoverflow.com/a/32261019/99717set -e
establece una opción de shell para salir inmediatamente si algún comando que se está ejecutando sale con un código de salida distinto de cero. El script volverá con el código de salida del comando que falla. Desde la página de manual de bash:exec "[email protected]"
se usa generalmente para hacer que el punto de entrada sea un paso que luego ejecuta el comando docker. Reemplazará el shell en ejecución actual con el comando al que"[email protected]"
apunta. De forma predeterminada, esa variable apunta a los argumentos de la línea de comandos.Si tiene una imagen con un punto de entrada que apunta a entrypoint.sh y ejecuta su contenedor como
docker run my_image server start
, eso se traducirá en ejecutarseentrypoint.sh server start
en el contenedor. En la línea ejecutivaentrypoint.sh
, el shell que se ejecuta como pid 1 se reemplazará por el comandoserver start
.Esto es fundamental para el manejo de señales. Sin usarlo
exec
, elserver start
del ejemplo anterior se ejecutaría como otro pid y, después de salir, volvería a su script de shell. Con un shell en pid 1, un SIGTERM se ignorará por defecto. Eso significa quedocker stop
elserver
proceso nunca recibiría la elegante señal de parada que envía a su contenedor . Después de 10 segundos (por defecto),docker stop
renunciaría al cierre ordenado y enviaría un SIGKILL que obligará a su aplicación a salir, pero con una posible pérdida de datos o conexiones de red cerradas, que los desarrolladores de la aplicación podrían haber codificado si recibieron la señal. También significa que su contenedor siempre tardará 10 segundos en detenerse.Tenga en cuenta que con comandos de shell como
shift
yset --
, puede cambiar el valor de"[email protected]"
. Por ejemplo, aquí hay una pequeña parte de un script que elimina el/bin/sh -c "..."
del comando que puede aparecer si usa la sintaxis de shell de Docker paraCMD
:# convert `/bin/sh -c "server start"` to `server start` if [ $# -gt 1 ] && [ x"$1" = x"/bin/sh" ] && [ x"$2" = x"-c" ]; then shift 2 eval "set -- $1" fi .... exec "[email protected]"
fuente
test
especificación POSIX , que marca-a
obsolescencia.[ "$#" -gt 1 ] && [ "$1" = /bin/sh ]
es el reemplazo correcto (no hay necesidad dex"$1"
piratería cuando se usa solo la sintaxis no obsoleta).shift 2; set -- $1
no es en absoluto lo mismo que cómoeval
analizará la cadena. Considere/bin/sh -c 'printf "%s\n" "hello world" "goodbye world"'
, si desea un caso de prueba concreto y vea que Bash no analiza las comillas al convertir una cadena en argumentos .eval
, creo que todavía quiero que refleje el comportamiento/bin/sh -c
que tendría en la cadena, pero avíseme si me falta algo.set -e
- salir del script si falla algún comando (valor distinto de cero)exec "[email protected]"
- redireccionará las variables de entrada, vea más aquífuente
exec
ciertamente tiene un modo de uso en el que realiza redirecciones, pero este no es ese modo.