Percebi que muitos scripts entrypoint.sh para docker fazem algo assim:
#!/bin/bash
set -e
... code ...
exec "[email protected]"
Para que servem set -e
e exec "[email protected]"
para?
Percebi que muitos scripts entrypoint.sh para docker fazem algo assim:
#!/bin/bash
set -e
... code ...
exec "[email protected]"
Para que servem set -e
e exec "[email protected]"
para?
set -e
é considerado muito mais sujeito a erros do que o tratamento de erros escrito à mão. (Se estiver com pressa, pule a analogia no topo para os exercícios abaixo).Respostas:
Basicamente, ele pega quaisquer argumentos de linha de comando passados
entrypoint.sh
e os executa como um comando. A intenção é basicamente "Faça tudo neste script .sh, então no mesmo shell execute o comando que o usuário passa na linha de comando".Vejo:
fonte
exec "[email protected]"
isso substituirá o processo em execução pelo novo processo gerado para os argumentos passados. Importante para a sinalização do Docker: stackoverflow.com/a/32261019/99717set -e
define uma opção do shell para sair imediatamente se qualquer comando executado sair com um código de saída diferente de zero. O script retornará com o código de saída do comando com falha. Na página de manual do bash:exec "[email protected]"
é normalmente usado para fazer do ponto de entrada uma passagem que executa o comando docker. Ele irá substituir o shell em execução atual pelo comando que"[email protected]"
está apontando para. Por padrão, essa variável aponta para os argumentos da linha de comando.Se você tiver uma imagem com um entrypoint apontando para entrypoint.sh e executar seu contêiner como
docker run my_image server start
, isso se traduzirá em execuçãoentrypoint.sh server start
no contêiner. Na linha execentrypoint.sh
, o shell em execução como pid 1 se substituirá pelo comandoserver start
.Isso é crítico para o tratamento do sinal. Sem usar
exec
, oserver start
no exemplo acima seria executado como outro pid e, depois de sair, você retornaria ao seu script de shell. Com um shell em pid 1, um SIGTERM será ignorado por padrão. Isso significa que o sinal de parada normal quedocker stop
envia para o seu contêiner nunca seria recebido peloserver
processo. Após 10 segundos (por padrão),docker stop
desistiria do desligamento normal e enviaria um SIGKILL que forçará seu aplicativo a sair, mas com possível perda de dados ou conexões de rede fechadas, que os desenvolvedores de aplicativos poderiam ter codificado se tivessem recebido o sinal. Isso também significa que seu contêiner sempre levará 10 segundos para parar.Observe que com comandos de shell como
shift
eset --
, você pode alterar o valor de"[email protected]"
. Por exemplo, aqui está uma pequena parte de um script que remove o/bin/sh -c "..."
do comando que pode aparecer se você usar a sintaxe do shell do 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]"
fonte
test
especificação POSIX , que marca-a
obsoleta.[ "$#" -gt 1 ] && [ "$1" = /bin/sh ]
é a substituição correta (não há necessidade dex"$1"
hackery ao usar apenas a sintaxe não obsoleta).shift 2; set -- $1
não é o mesmo queeval
analisar a string. Considere/bin/sh -c 'printf "%s\n" "hello world" "goodbye world"'
, se você deseja um caso de teste concreto, e veja que o Bash não analisa aspas ao converter uma string em argumentos .eval
, acredito que ainda quero espelhar o comportamento de/bin/sh -c
teria na string, mas, por favor, me diga se estou faltando alguma coisa.set -e
- saia do script se algum comando falhar (valor diferente de zero)exec "[email protected]"
- redirecionará variáveis de entrada, veja mais aquifonte
exec
certamente tem um modo de uso em que está realizando redirecionamentos, mas este não é esse modo.