Значение “исполнительного хвоста-n +3” строки за 0$ в 40_custom файл

Я пытаюсь понять файлы конфигурации личинки. Так, во время этого процесса я столкнулся с файлом/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 следует за ним. Так, это - просто (бесполезная) конвенция?

17
задан 7 January 2019 в 02:40

3 ответа

Прием что 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 использует его собственный язык сценариев, и это заставляет его нуждаться в этом обходном решении.

16
ответ дан 23 November 2019 в 02:21

Каталог /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.

9
ответ дан 23 November 2019 в 02:21

TL; DR: это - прием для упрощения добавляющих новых записей в файл

Самое главное описано на одной из страниц Ubuntu's Wiki на личинке:

  1. Только исполняемые файлы генерируют вывод к 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 можно просто добавить через >> в оболочке в этот файл.

См. также:

3
ответ дан 23 November 2019 в 02:21

Другие вопросы по тегам:

Похожие вопросы: