Добавить к существующей переменной в файле

Вопрос или проблема

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

Оцените материал
Добавить комментарий

Капча загружается...