Используйте sed (или awk), чтобы добавить запись в fstab, когда совпадение найдено - PullRequest
0 голосов
/ 04 октября 2019

Мне нужно отредактировать строки в / etc / fstab и добавить / изменить fsoptions в строки, где найден соответствующий объем. Я пытался использовать sed и помещать найденные блоки в регистры, чтобы поместить их обратно, но я нахожу это проблемой. Возможно, sed не лучший инструмент - я пробовал augeas, и хотя он добавляет, он не заменил, а также потерпел неудачу, если соответствующая строка не была найдена, но ее нужно было добавить (например, она была видна только с помощью команды mount, такой как / dev). /shm).

например, если / etc / fstab имеет строку:

/dev/mapper/VolGroup1-tmp /tmp                    xfs     dev,nosuid 0 0

Я хочу сделать это

/dev/mapper/VolGroup1-tmp /tmp                    xfs     nodev,nosuid,noexec 0 0
  1. Обратите внимание, чтогруппа томов в первом блоке может иметь любое имя
  2. КЛЮЧЕВОЕ СЛОВО в строке (в этом примере) будет / tmp (но будьте осторожны, чтобы не совпадать с / var / tmp, если не указано)
  3. Файловая система может быть чем угодно (не обязательно xfs)
  4. Любой присутствующий 'exec' или 'suid' (например) должен быть заменен, если присутствует, и даже если нет, вставлен 'noexec' или 'nosuid'.
  5. Трейлинг '0 0' необходимо сохранить.

Я уверен, что мне не хватает простого способа сделать это. Использование 'mount -o remount, noexec / tmp' не записывает в / etc / fstab, поэтому я думаю, что единственный способ сделать изменения постоянными - это отредактировать / etc / fstab напрямую?

Я действительно собираюсьоберните раствор в кукольный. Приведенный ниже пример augeas завершается с ошибкой в ​​2 случаях:

  • , если в / etc / fstab не существует строки (например, / dev / shm), она завершается с ошибкой

  • , если строка существует и имеет 'exec', она добавляет 'noexec', но оставляет exec также

      augeas{ "/etc/fstab - ${opt} on ${mount}":
    context => '/files/etc/fstab',
    changes => [
      "ins opt after /files/etc/fstab/*[file = '${mount}']/opt[last()]",
      "set *[file = '${mount}']/opt[last()] ${opt}",
    ],
    onlyif  => "match *[file = '${mount}']/opt[. = '${opt}'] size == 0",
    notify  => Exec["remount_${mount}_${opt}"],
    

    }

1 Ответ

3 голосов
/ 05 октября 2019

Я уверен, что мне не хватает простого способа сделать это. Использование 'mount -o remount, noexec / tmp' не записывает в / etc / fstab, поэтому я думаю, что единственный способ сделать изменения постоянными - это отредактировать / etc / fstab напрямую?

Естьнет специального CLI для изменения записей монтирования в / etc / fstab, если вы это имеете в виду. Редактирование файла вручную с помощью текстового редактора является традиционным способом.

Как я уже упоминал в комментариях, стандартный подход Puppet для работы с записями монтирования заключается в использовании ресурсов Mount. Пока я пишу ответ, я повторяю, что с их помощью вы должны выполнять свою работу.

Вы возразили в комментариях, что

проблема в том, чтопервая строка (fsname) может быть чем угодно, как и fstype. Я также хочу сохранить существующие функции, которые не конфликтуют с новыми желаемыми настройками.

Это является проблемой, но не так, как я думаю, вы имеете в виду. Вы находитесь в затруднительном положении, потому что вы пытаетесь приспособить несколько авторитетов к этому аспекту конфигураций ваших узлов. Лучшей практикой было бы возложить ответственность за горы интереса на Марионетку. У него более чем достаточно гибкости для обеспечения различных конфигураций монтирования на разных машинах.

Однако, если вы решили использовать Puppet таким образом, это можно сделать. Но хотя задачу относительно легко описать, подробности делают ее относительно сложной. Подход, основанный на sed, возможен, но будет сравнительно длинным и крайне загадочным. Лучшим инструментом командной строки для основного задания будет awk, и, в частности, этот сценарий awk выполнит работу для представленного вами случая:

$1 ~ /^#.*/ || $2 != "/tmp" {print; next}
$4 ~ /.*nosuid.*/ && $4 ~ /.*noexec.*/ {print; next}
{
  split($4, opts, ",")
  printf "%s    %s  %s  ", $1, $2, $3
  for (i in opts) {
    if (opts[i] !~ /(no)?(exec|suid)/) {
      printf "%s,", opts[i]
    }
  }
  printf "noexec,nosuid %s %s\n", $5, $6
}

Оборачивая это вExec Ресурс и любые другие приспособления к вашим конкретным требованиям оставлены в качестве упражнения.

...