Estoy tratando de entender los archivos de configuración de grub. Entonces, durante este proceso, me encontré con el archivo /etc/grub.d/40_custom . Mi archivo contiene las siguientes líneas:
#!/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 mi sistema es de arranque dual y aparentemente este es el gestor de arranque para Windows 10.
Sin embargo, mi pregunta es esta parte exec tail -n +3 $0
.
Si lo estoy descifrando correctamente, esto solo significa imprimir las últimas líneas a partir de la tercera línea ( +3
) del archivo $0
. $0
Por supuesto, en este caso es el archivo real /etc/grub.d/40_custom .
Entonces, ¿por qué usamos este comando en el archivo 40_custom ? A medida que lo entiendo, la salida sería la misma si se omitiera por completo. Lo único diferente en lo que podría pensar es en la primera línea que identifica al intérprete:
#!/bin/sh
Pero, de nuevo, se ejecuta ya que lo exec tail -n +3 $0
sigue. Entonces, ¿es solo una convención (inútil)?
#!/bin/tail -n +2
como un shellbang? ¿Imprimirá el resto del archivo?-n +2
parece interpretarse como-n 2
y solo se imprimen las dos últimas líneas. Sin embargo, eso probablemente valga su propia pregunta.n
y el+
. Al menos en Linux, después de la ruta ejecutable y un espacio, los siguientes caracteres se tratan como un argumento único. Entonces, con el espacio, tail lo ve y probablemente decide eliminar cualquier-n
argumento de prefijo no válido (en este caso, un espacio y a+
) hasta que llegue al número. Sin embargo, como dijo Charles Duffy, la forma actual en que lo hicieron es probablemente más portátil para otros Unices.cat <<EOF ...EOF
allíEl directorio
/etc/grub.d/
contiene muchos ejecutables (generalmente scripts de shell, pero también es posible cualquier otro tipo de ejecutable). Siempre quegrub-mkconfig
se ejecuta (por ejemplo, si ejecutaupdate-grub
, pero también cuando instala un paquete de kernel actualizado, que generalmente tiene un enlace posterior a la instalación que le indica al administrador del paquete que actualicegrub.cfg
), todos se ejecutan en orden alfabético. Todos sus resultados se concatenan y terminan en el archivo/boot/grub/grub.cfg
, con encabezados de sección que muestran qué parte proviene de qué/etc/grub.d/
archivo.Este archivo en particular
40_custom
está diseñado para permitirle agregar fácilmente entradas / líneasgrub.cfg
simplemente escribiéndolas / pegándolas en este archivo. Otros scripts en el mismo directorio realizan tareas más complejas, como buscar núcleos o sistemas operativos que no sean Linux y crear entradas de menú para ellos.Para permitir
grub-mkconfig
tratar todos esos archivos de la misma manera (ejecutar y tomar la salida),40_custom
es un script y utiliza esteexec tail -n +3 $0
mecanismo para generar su contenido (menos el "encabezado"). Si no fuera un ejecutable,update-grub
necesitaría una excepción especial codificada para tomar el contenido de texto literal de este archivo en lugar de ejecutarlo como todos los demás. Pero entonces, ¿qué pasa si usted (o los creadores de otra distribución de Linux) quiere darle a este archivo un nombre diferente? ¿O qué pasa si no sabía sobre la excepción y creó un script de shell llamado40_custom
?Puede leer más sobre
grub-mkconfig
y/etc/grub.d/*
en el Manual de GNU GRUB (aunque habla principalmente de las opciones que puede configurar/etc/default/grub
), y también debe haber un archivo/etc/grub.d/README
que indique que estos archivos se ejecutan para formarsegrub.cfg
.fuente
/etc/grub.d/exec
para archivos / scripts ejecutables, y/etc/grub.d/static
para archivos de texto sin formato, o algún otro indicador para distinguirlos. Sin embargo, esta fue la decisión de diseño que tomaron.TL; DR : es un truco para simplificar la adición de nuevas entradas al archivo
Todo el punto se describe en una de las páginas Wiki de Ubuntu en grub :
La salida de scripts en se
/etc/grub.d/
convierte en el contenido delgrub.cfg
archivo.¿Ahora que hace
exec
? Puede volver a cablear la salida para el script completo o si se proporciona un comando: el comando mencionado supera y reemplaza el proceso del script. Lo que una vez fue script de shell con PID 1234 ahora estail
comando con PID 1234.Ahora ya sabe que
tail -n +3 $0
imprime todo después de la tercera línea en el script en sí. Entonces, ¿por qué necesitamos hacer esto? Si grub solo se preocupa por la salida, también podríamos hacerloDe hecho, encontrará
cat <<EOF
ejemplos en la documentación de Fedora , aunque para un propósito diferente. El punto principal está en los comentarios: facilidad de uso para los usuarios:Con
exec
truco, no tienes que saber qué hacecat <<EOF
(spoiler, eso se llama here-doc ), ni debes recordar agregar elEOF
en la última línea. Simplemente agregue menuentry al archivo y termine con él. Además, si está creando una secuencia de comandos para agregar un menú, simplemente puede agregarlo>>
en shell a este archivo.Ver también:
fuente
#!/bin/sh
en ese caso. Sospecho que esto es simplemente una razón histórica (transferida de la base de código PUPA ) y una decisión de diseño inspirada en el tipo de scripting SysV.