Вопрос или проблема
У меня есть файл параметров Grub, который я хочу изменить с помощью скрипта. Я хочу добавить дополнительные параметры загрузчика.
Файл может изменяться со временем, поэтому я хочу создать что-то, что адаптируется к будущим релизам, добавляя к тем параметрам загрузчика, которые идут с образом.
Например, файл загрузчика содержит следующее:
# Установить тайм-аут записи ошибки
GRUB_RECORDFAIL_TIMEOUT=0
# Не ждать на приглашении grub
GRUB_TIMEOUT=0
# Установить стандартную командную строку
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0"
# Установить тип консоли grub
GRUB_TERMINAL=console
GRUB_HIDDEN_TIMEOUT=0.1
Я хочу добавить к строке GRUB_CMDLINE_LINUX_DEFAULT так, чтобы она выглядела следующим образом:
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0 cgroup_enable=memory swapaccount=1"
Есть ли способ сделать это с помощью sed или awk? Что-то вроде “добавить перед последней кавычкой строки, содержащей GRUB_CMDLINE_LINUX_DEFAULT”.
Заранее спасибо!
Просто с sed
:
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& cgroup_enable=memory swapaccount=1/' файл
[^"]*
– соответствует любому символу, кроме двойной кавычки"
&
– вся совпавшая строка (действующее пространство шаблона)
При добавлении чего-то к переменной в /etc/default/grub
или похожем, часто удобно делать это идемпотентным, например, вот так:
function f { sed '/^GRUB_CMDLINE_LINUX_DEFAULT="[^"]*'"$1"'[^"]*"/!s/^GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& '"$1""https://unix.stackexchange.com/" /путь/к/grub -i ; }; f 'cgroup_enable=memory swapaccount=1'
Таким образом, вы ограничиваете команду sed s
строками, которые не содержат уже вашего целевого изменения cgroup_enable=memory swapaccount=1
, так что безопасно выполнять изменение несколько раз.
В противном случае ваши параметры будут добавляться несколько раз, даже если они уже присутствуют.
/etc/default/grub
должен быть в синтаксисе sh
. Этот файл может содержать, например:
GRUB_CMDLINE_LINUX_DEFAULT=что угодно
GRUB_CMDLINE_LINUX_DEFAULT='какой-то параметр'
GRUB_CMDLINE_LINUX_DEFAULT="какой-то параметр" # был "другой параметр"
GRUB_CMDLINE_LINUX_DEFAULT="\
какой-то \
параметр"
GRUB_CMDLINE_LINUX_DEFAULT='какой-то параметр' GRUB_CMDLINE_LINE=foo
if что-то; then
IFS= read -r GRUB_CMDLINE_LINUX_DEFAULT < /proc/cmdline
else
GRUB_CMDLINE_LINUX_DEFAULT=$(get-default-grub-config)
fi
cat << 'EOF' >> /var/log/grub-config.log
GRUB_CMDLINE_LINUX_DEFAULT=бла
EOF
Практически невозможно учесть все возможные случаи.
Однако вам не нужно, вы можете просто использовать код оболочки, чтобы добавить что-то к переменной, добавив:
echo '
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT cgroup_enable=memory swapaccount=1"' >> /etc/default/grub
Ubuntu и Debian также читают .cfg
файлы в /etc/default/grub.d
, что облегчает управление локальными/настраиваемыми добавлениями, где вам просто нужно добавить файл, содержащий:
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT cgroup_enable=memory swapaccount=1"
В /etc/default/grub.d
. Однако вы захотите убедиться, что он обрабатывается последним (или, по крайней мере, после всех тех, которые устанавливают или изменяют $GRUB_CMDLINE_LINUX_DEFAULT
. Не похоже, что соглашение об именовании подразумевает их нумерацию, поэтому вам может потребоваться сделать что-то вроде:
cat << 'EOF' > /etc/default/grub.d/zzz-my-additions.cfg
# объяснить, почему я добавляю это
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT cgroup_enable=memory swapaccount=1"
EOF
Или даже иметь отдельный файл для каждого параметра.
Ответ или решение
Как добавить параметры загрузчика к существующей переменной в файле GRUB
Модификация конфигурационных файлов, таких как /etc/default/grub
, является важной задачей для системных администраторов и разработчиков, желающих адаптировать параметры загрузчика под свои нужды. В этой статье подробно рассматривается, как можно добавить дополнительные параметры к существующей переменной GRUB_CMDLINE_LINUX_DEFAULT
в файле GRUB с помощью утилит sed
и awk
.
Исходное состояние
В вашем файле GRUB вы имеете следующую конфигурацию:
# Устанавливаем время ожидания при сбое
GRUB_RECORDFAIL_TIMEOUT=0
# Не ждать на приглашении grub
GRUB_TIMEOUT=0
# Устанавливаем базовые параметры командной строки
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0"
# Устанавливаем тип консоли Grub
GRUB_TERMINAL=console
GRUB_HIDDEN_TIMEOUT=0.1
Цель: Добавление параметров
Вы хотите, чтобы строка GRUB_CMDLINE_LINUX_DEFAULT
в конце выглядела следующим образом:
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0 cgroup_enable=memory swapaccount=1"
Решение с использованием sed
Использование sed
позволяет вам модифицировать строки в файле прямо из командной строки. Для решения вашей задачи вы можете использовать следующую команду:
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& cgroup_enable=memory swapaccount=1/' /etc/default/grub
Разбор команды:
-i
— делает изменения на месте, не создавая временный файл.s/.../.../
— команда замены вsed
.GRUB_CMDLINE_LINUX_DEFAULT="[^"]*
— регулярное выражение, которое находит строку, начинающуюся сGRUB_CMDLINE_LINUX_DEFAULT="
и продолжающуюся до следующей кавычки.&
— соответствует найденной строке и позволяет сохранить её, добавляя к ней нужные параметры.
Учёт идемпотентности
Для того чтобы избежать повторного добавления одного и того же параметра при многократном выполнении скрипта, можно создать функцию, которая будет проверять наличие нужных параметров перед их добавлением:
function append_grub_cmd {
local new_params="$1"
sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT="[^"]*'"$new_params"'[^"]*"/!s/^GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& '"$new_params"'/g' /etc/default/grub
}
append_grub_cmd 'cgroup_enable=memory swapaccount=1'
В этом примере в качестве параметра функции передается новая строка с параметрами, и только если они ещё не добавлены, sed
проведёт модификацию.
Другие подходы
Если необходимо учесть различные формы записи переменной или случаи, когда файл может быть в формате sh
, имейте в виду, что можно использовать простую конструкцию:
echo '
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT cgroup_enable=memory swapaccount=1"' >> /etc/default/grub
Использование каталога конфигурации GRUB
Ubuntu и Debian предоставляют удобную механизм для управления изменениями конфигурации загрузчика через каталог /etc/default/grub.d/
. Создание отдельного файла для пользовательских настроек может упорядочить процесс и избежать конфликтов:
cat << 'EOF' > /etc/default/grub.d/zzz-my-additions.cfg
# Объясняем, почему мы добавляем эти параметры
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT cgroup_enable=memory swapaccount=1"
EOF
Имя файла начинается с zzz-
, чтобы гарантировать его обработку после всех других файлов, задающих или модифицирующих GRUB_CMDLINE_LINUX_DEFAULT
.
Заключение
Модификация параметров загрузчика GRUB является критически важной задачей, которая требует осторожности. Использование sed
и подходящей структуры папок для конфигурационных файлов обеспечивает гибкость и безопасность. С помощью вышеописанных методов вы можете адаптировать свои скрипты для будущих обновлений и изменений, сохраняя целостность и простоту управления конфигурацией.