Estou tentando entender os arquivos de configuração do grub. Então, durante esse processo, me deparei com o arquivo /etc/grub.d/40_custom . Meu arquivo contém as seguintes linhas:
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry "Windows 10" --class windows --class os {
insmod part_msdos
savedefault
insmod ntfs
insmod ntldr
set root='(hd0,msdos1)'
ntldr ($root)/bootmgr
}
como o meu sistema é de inicialização dupla e, aparentemente, este é o carregador de inicialização para o Windows 10.
Minha pergunta é essa parte exec tail -n +3 $0
.
Se eu estiver decifrando corretamente, isso significa imprimir as últimas linhas a partir da 3ª linha ( +3
) do arquivo $0
. $0
é claro que, neste caso, é o arquivo real /etc/grub.d/40_custom .
Então, por que usamos este comando no arquivo 40_custom ? Na minha opinião, a saída seria a mesma se fosse omitido por completo. A única diferença em que posso pensar é a 1ª linha que identifica o intérprete:
#!/bin/sh
Mas, novamente, é executado desde que o exec tail -n +3 $0
segue. Então, isso é apenas uma convenção (inútil)?
#!/bin/tail -n +2
como um shellbang? Irá imprimir o restante do arquivo?-n +2
parece ser interpretado como-n 2
e apenas as duas últimas linhas são impressas. Provavelmente isso vale sua própria pergunta.n
e o+
. No Linux, pelo menos, após o caminho executável e um espaço, os seguintes caracteres são tratados como um único argumento. Portanto, com o espaço, o tail o vê e provavelmente decide remover qualquer-n
argumento do prefixo inválido (neste caso, um espaço e a+
) até chegar ao número. No entanto, como Charles Duffy disse, a maneira atual como eles fizeram isso é provavelmente mais portátil para outros Unices.cat <<EOF ...EOF
láO diretório
/etc/grub.d/
contém muitos executáveis (normalmente shell scripts, mas qualquer outro tipo de executável também é possível). Sempre quegrub-mkconfig
é executado (por exemplo, se você executaupdate-grub
, mas também quando instala um pacote atualizado do kernel, que geralmente possui um gancho pós-instalação que instrui o gerenciador de pacotes a atualizargrub.cfg
), todos são executados em ordem alfabética. Todas as saídas são concatenadas e acabam no arquivo/boot/grub/grub.cfg
, com cabeçalhos de seção organizados que mostram qual parte vem de qual/etc/grub.d/
arquivo.Este arquivo específico
40_custom
foi projetado para permitir que você adicione entradas / linhas facilmentegrub.cfg
, simplesmente digitando / colando-as nesse arquivo. Outros scripts no mesmo diretório executam tarefas mais complexas, como procurar kernels ou sistemas operacionais não-linux e criar entradas de menu para eles.Para permitir
grub-mkconfig
tratar todos esses arquivos da mesma maneira (executar e obter a saída),40_custom
é um script e usa esseexec tail -n +3 $0
mecanismo para gerar seu conteúdo (menos o "cabeçalho"). Se não fosse um executável,update-grub
seria necessária uma exceção especial codificada para pegar o conteúdo de texto literal desse arquivo, em vez de executá-lo como todos os outros. Mas e se você (ou os fabricantes de outra distribuição Linux) quiser dar um nome diferente a esse arquivo? Ou, e se você não soubesse da exceção e criava um script de shell com o nome40_custom
?Você pode ler mais sobre
grub-mkconfig
e/etc/grub.d/*
no Manual do GNU GRUB (embora ele fale principalmente sobre as opções que você pode definir/etc/default/grub
), e também deve haver um arquivo/etc/grub.d/README
informando que esses arquivos são executados para formargrub.cfg
.fonte
/etc/grub.d/exec
arquivos / scripts executáveis e/etc/grub.d/static
arquivos de texto sem formatação, ou algum outro indicador para diferenciá-los. No entanto, essa foi a decisão de design que eles adotaram.TL; DR : é um truque para simplificar a adição de novas entradas ao arquivo
O ponto todo é descrito em uma das páginas Wiki do Ubuntu no grub :
A saída de scripts
/etc/grub.d/
torna-se o conteúdo dogrub.cfg
arquivo.Agora, o que
exec
faz? Ele pode reconectar a saída de todo o script ou se um comando for fornecido - o comando mencionado ultrapassa e substitui o processo de script. O que antes era o script de shell com o PID 1234 agora é otail
comando com o PID 1234.Agora você já sabe que
tail -n +3 $0
imprime tudo após a terceira linha no próprio script. Então, por que precisamos fazer isso? Se o grub se importar apenas com a saída, poderíamos fazer o mesmoDe fato, você encontrará
cat <<EOF
exemplos na documentação do Fedora , embora para um propósito diferente. O ponto principal está nos comentários - facilidade de uso para os usuários:Com
exec
truque, você não precisa saber o quecat <<EOF
faz (spoiler, que é chamado aqui-doc ), nem precisa se lembrar de adicionarEOF
a última linha. Basta adicionar menuentry ao arquivo e pronto. Além disso, se você estiver adicionando uma entrada de menu ao script, basta anexar via>>
shell neste arquivo.Veja também:
fonte
#!/bin/sh
nesse caso. Suspeito que esse seja simplesmente um motivo histórico ( herdado da base de código PUPA ) e uma decisão de design inspirada no tipo de script SysV.