Relacionado: Qual interpretador de shell executa um script sem shebang?
O script não possui uma linha shebang / hashbang / #!
, simplesmente porque não há um traço duplo #!
.
No entanto, o script será executado por um shell (veja as perguntas e respostas vinculadas acima) e, nesse shell, se -
for um caractere válido em um nome de função, a linha declara uma função do shell chamada --
que não faz nada (bem, ele executa :
, que não faz nada ) e que nunca é chamado.
A função, na notação multilinha mais comum (apenas para tornar mais óbvio o que parece, pois seu nome estranho meio que obscurece o fato de que é de fato uma função):
-- () {
:
}
O único objetivo da definição da função é ter uma linha válida em um script de shell e, ao mesmo tempo, um comando SQL válido (um comentário). Esse tipo de código é chamado poliglota .
Após declarar a função de shell falsa, o script, quando executado por um interpretador de script de shell, usa exec
para substituir o shell atual pelo processo resultante da execução db2 -txf "$0"
, o que seria o mesmo que usar db2 -txf
no nome do caminho do script na linha de comando.
Esse truque provavelmente não funcionaria de maneira confiável em sistemas em que dash
ou em outros ash
shells baseados em shell, yash
o shell Bourne, ksh88
ou ksh93
é usado como /bin/sh
, pois esse shell não aceita funções cujo nome contenha hífens.
Também relacionado:
Suponho que o seguinte também funcionaria (não realmente testado):
--() { exec db2 -txf "$0"; }; --
Como o @Kusalananda já disse, esse truque está quebrado e não funcionará em todos os aspectos.
Aqui está minha opinião sobre como fazê-lo de maneira portável:
O primeiro comando deve falhar, mesmo que
--
exista um arquivo / diretório nomeado no diretório atual e quaisquer erros sejam encerrados pelo2>/dev/null
; o shell continuará com o segundo comando, oexec
.fonte
ENOEXEC
se você tentar. Tente executar o script abaixostrace
para ver o que quero dizer.exec()
não funcionar. "Se a função execl () falhar devido a um erro equivalente ao erro [ENOEXEC], o shell executará um comando equivalente a ter um shell invocado com o nome do comando como seu primeiro operando, ..." (consulte pubs.opengroup .org / onlinepubs / 9699919799.2018edition / utilities /… )exec()
diretamente de algo diferente de um shell. Mas qual seria esse caso? Você pode querer executar o script a partir de algocron
assim, mas acho que ele executa tudo através de um shell de qualquer maneira, e mesmo se não for, é fácil explicardb2 -txf /path/to/script
nesse caso, já que você só precisa fazê-lo uma vez. Ter o trabalho taquigráfico é muito útil em um shell interativo. Mas com certeza, um script de wrapper separado pode ser mais robusto.echo 'int main(int c,char**a){execvp(a[1],a+1);}' | cc -include unistd.h -xc -; echo echo yeah > a.sh; chmod 755 a.sh; ./a.out ./a.sh; PATH=`pwd` ./a.out a.sh