Eu tenho visto isso em muitos docker-entrypoint.shscripts recentemente e não consigo encontrar uma explicação online. Meus primeiros pensamentos são que é algo a ver com sinalização, mas isso é um palpite bem louco.
O "$@"bit se expandirá para a lista de parâmetros posicionais (geralmente os argumentos da linha de comando), citados individualmente para evitar a divisão de palavras e a geração de nomes de arquivos ("globbing").
O execsubstituirá o processo atual pelo processo resultante da execução de seu argumento.
Em suma, exec "$@"executará o comando fornecido pelos parâmetros da linha de comando de forma que o processo atual seja substituído por ele (se execfor capaz de executar o comando).
"$@"em shells semelhantes a Bourne, em contextos de lista se expande para todos os parâmetros posicionais como argumentos separados.
Em um script, inicialmente, os parâmetros posicionais são os argumentos que o próprio script recebeu.
execé executar um comando no mesmo processo que o shell. Esse é o último comando que um script executará porque depois disso, o processo estará executando outro comando além do shell.
Então, se o seu script é
#! /bin/sh -
exec "$@"
E você chama seu script usando uma linha de comando do shell como:
/path/to/your-script 'echo' "some test" 'x y'
Ele chamará execcom echo, some teste x ycomo argumentos que serão executados echo(na maioria das shimplementações, /bin/echoao contrário do echoshell embutido) no mesmo processo que estava executando anteriormente o shell interpretando seu script com some teste x ycomo argumentos.
Isso é importante no Docker para que os sinais sejam proxy corretamente. Por exemplo, se o Redis foi iniciado sem exec, ele não receberá um SIGTERMupon docker stope não terá a chance de ser encerrado corretamente. Em alguns casos, isso pode levar à perda de dados ou processos zumbis.
Se você iniciar processos filho (ou seja, não usar exec), o processo pai se tornará responsável por manipular e encaminhar sinais conforme apropriado. Essa é uma das razões pelas quais é melhor usar supervisordou similar ao executar vários processos em um contêiner, pois ele encaminhará os sinais adequadamente.
O
"$@"
bit se expandirá para a lista de parâmetros posicionais (geralmente os argumentos da linha de comando), citados individualmente para evitar a divisão de palavras e a geração de nomes de arquivos ("globbing").O
exec
substituirá o processo atual pelo processo resultante da execução de seu argumento.Em suma,
exec "$@"
executará o comando fornecido pelos parâmetros da linha de comando de forma que o processo atual seja substituído por ele (seexec
for capaz de executar o comando)."$@"
em shells semelhantes a Bourne, em contextos de lista se expande para todos os parâmetros posicionais como argumentos separados.Em um script, inicialmente, os parâmetros posicionais são os argumentos que o próprio script recebeu.
exec
é executar um comando no mesmo processo que o shell. Esse é o último comando que um script executará porque depois disso, o processo estará executando outro comando além do shell.Então, se o seu script é
E você chama seu script usando uma linha de comando do shell como:
Ele chamará
exec
comecho
,some test
ex y
como argumentos que serão executadosecho
(na maioria dassh
implementações,/bin/echo
ao contrário doecho
shell embutido) no mesmo processo que estava executando anteriormente o shell interpretando seu script comsome test
ex y
como argumentos.Duas outras respostas explicam o que
exec "$@"
faz. Esta resposta no Stack Overflow explica por que é importante para o Docker e, como você supõe, tem a ver com sinais: