Я пытаюсь понять файлы конфигурации личинки. Так, во время этого процесса я столкнулся с файлом/etc/grub.d/40_custom. Мой файл содержит следующие строки:
#!/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
}
поскольку моя система является двойной загрузкой, и по-видимому это - загрузчик для окон 10.
Мой вопрос, хотя эта часть exec tail -n +3 $0
.
Если я дешифрую его правильно, это просто означает, печатают последние строки, начинающие с 3-й строки (+3
) из файла $0
. $0
конечно, в этом случае фактический файл/etc/grub.d/40_custom.
Так, почему мы используем эту команду в 40_custom файл? Поскольку я получаю его, вывод был бы тем же, если бы ιt был опущен в целом. Единственной другой, о которой я мог бы думать, является 1-я строка, которая определяет интерпретатор:
#!/bin/sh
Но с другой стороны это выполняется с тех пор exec tail -n +3 $0
следует за ним. Так, это - просто (бесполезная) конвенция?
Прием что exec
делает:
$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
Replace the shell with the given command.
Execute COMMAND, replacing this shell with the specified program.
ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,
any redirections take effect in the current shell.
Это означает, что заменит оболочку тем, чему дают exec
, в этом случае tail
. Вот пример его в действии:
$ cat ~/foo.sh
#!/bin/sh
exec tail -n +3 "$0"
echo foo
$ ./foo.sh
echo foo
Так echo
команда не выполняется, так как мы изменили оболочку и используем tail
вместо этого. Если мы удаляем exec tail
:
$ cat ~/foo.sh
#!/bin/sh
echo foo
$ ./foo.sh
foo
Так, это - аккуратный прием, который позволяет Вам записать сценарий, чей только задание состоит в том, чтобы произвести свое собственное содержание. По-видимому, безотносительно вызовов 40_custom
ожидает его содержание, как произведено. Конечно, это вызывает вопрос о почему не просто выполнение tail -n +3 /etc/grub.d/40_custom
непосредственно.
Я предполагаю, что ответ то, потому что grub
использует его собственный язык сценариев, и это заставляет его нуждаться в этом обходном решении.
Каталог /etc/grub.d/
содержит много исполняемых файлов (обычно сценарии оболочки, но любой другой исполняемый тип также возможен). Каждый раз, когда grub-mkconfig
выполняется (например, если Вы работаете update-grub
, но также и когда Вы устанавливаете обновленный пакет ядра, который обычно имеет рычаг постустановки, который говорит диспетчеру пакетов обновлять grub.cfg
), они все выполняются в алфавитном порядке. Их выводы все связываются, и закончите в файле /boot/grub/grub.cfg
, с аккуратными заголовками раздела, которые показывают, какая часть прибывает из который /etc/grub.d/
файл.
Этот конкретный файл 40_custom
разработан, чтобы позволить Вам легко добавлять записи/строки в grub.cfg
путем простого ввода/вставки их в этот файл. Другие сценарии в том же каталоге делают более сложные задачи как поиск ядер или неоперационных систем Linux и создания записей меню для них.
Для разрешения grub-mkconfig
рассматривать все те файлы таким же образом (выполняют и берут вывод), 40_custom
сценарий и использует это exec tail -n +3 $0
механизм для вывода его содержания (минус "заголовок"). Если это не был исполняемый файл, update-grub
нуждался бы в специальном трудно кодированном исключении для взятия содержания буквенного текста этого файла вместо того, чтобы выполнить его как все другие. Но затем что, если Вы (или производители другого дистрибутива Linux) хотите дать этому файлу другое имя? Или что, если Вы не знали об исключении и создали названный сценарий оболочки 40_custom
?
Можно читать больше о grub-mkconfig
и /etc/grub.d/*
в Руководстве GRUB GNU (хотя это говорит главным образом об опциях, можно начаться /etc/default/grub
), и должен также быть файл /etc/grub.d/README
это указывает, что эти файлы выполняются для формирования grub.cfg
.
TL; DR: это - прием для упрощения добавляющих новых записей в файл
Самое главное описано на одной из страниц Ubuntu's Wiki на личинке:
- Только исполняемые файлы генерируют вывод к grub.cfg во время выполнения личинки обновления.
Вывод сценариев в /etc/grub.d/
становится содержанием grub.cfg
файл.
Теперь, что делает exec
? Это может или повторно соединить вывод проводом для всего сценария или если команда обеспечивается - упомянутая команда настигает и заменяет процесс сценария. Что было однажды сценарий оболочки с PID, 1234 теперь tail
команда с PID 1234.
Теперь Вы уже знаете это tail -n +3 $0
печать все после 3-й строки в самом сценарии. Итак, почему мы должны сделать это? Если личинка только заботится о выводе, мы могли бы точно также сделать
cat <<EOF
menuentry {
...
}
EOF
На самом деле Вы найдете cat <<EOF
пример в документации Fedora, хотя для другой цели. Самое главное находится в комментариях - простота использования для пользователей:
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment.
С exec
прием, Вы не должны знать то, что делает cat <<EOF
сделайте (спойлер, это назвало здесь-документ), ни необходимо не забыть добавлять EOF
на последней строке. Просто добавьте menuentry к файлу и быть сделанными с ним. Плюс при сценариях добавления menuentry можно просто добавить через >>
в оболочке в этот файл.