Изменение правильного имени группы и идентификатора в файле /etc/group

Я передаю 2 парма в скрипт bash. Первый параметр - это группа, а второй - это идентификатор группы. Я хочу написать сценарий bash, который будет проверять, присутствует ли группа в /etc/group или нет. Если нет, то скрипт должен добавить группу и gid в /etc/group, Если он присутствует, он должен соответствовать gid со вторым параметром. Если gid не соответствует 2-му параметру, он должен перезаписать gid 2-м параметром.

Короче говоря, имя группы и гид, которые я передаю скрипту, должны быть в файле / etc / group.

Я запускаю команду как:

./addgroup.sh groupa 123

предполагать /etc/group имеет запись:

groupa:x:345

После запуска команды, когда я просматриваю /etc/group это должно иметь значение

groupa:x:123

Я написал следующее addgroup.sh до сих пор:

if grep -q "^$1:" /etc/group
then
    echo "group $1 exists:SUCCESS"
else
    grep -q "^$1:" /etc/group || /bin/echo "$1:x:$2:" >> /etc/group
    cat /etc/group
    echo "group $1 added:SUCCESS"
fi

2 ответа

Я считаю, что этот код отвечает вашим потребностям и проще:

{ grep -v "^$1:" /etc/group; echo "$1:x:$2:"; } >/etc/group.tmp && mv /etc/group.tmp /etc/group

В вопросе говорится, что вы хотели бы обновить идентификатор группы, даже если группа уже существует. Код здесь имеет эту функцию.

Как это устроено:

  • grep -v "^$1:" /etc/group

    Это удаляет существующее определение группы $1 если таковой существует.

  • echo "$1:x:$2:"

    Это добавляет правильное определение группы $1 с правильным идентификатором группы.

  • {...} && mv /etc/group.tmp /etc/group

    Если команды в фигурных скобках выполнены успешно, это обновляет /etc/group.

Сохранение существующих членов группы

Как указывает sjnarv, можно захотеть сохранить существующих членов группы. В таком случае:

awk -v g="$1" -v id="$2" -F: -i inplace '$1 == g{save=$4; next} {print} ENDFILE{print g, "x", id, save}' OFS=: /etc/group

Это требует GNU awk. (В Ubuntu доступен GNU awk, но обычно он не используется по умолчанию.) Для стандартного awk:

awk -v g="$1" -v id="$2" -F: '$1 == g{save=$4; next} {print} END{print g, "x", id, save}' OFS=: /etc/group > /etc/group.tmp && mv /etc/group.tmp /etc/group

Как это устроено:

  • -v g="$1" -v id="$2"

    Это использует переменные оболочки $1 а также $2 определить две переменные awk g а также id,

  • -F:

    Это говорит о том, что наш разделитель полей :,

  • -i inplace

    Это говорит awk об изменении файла на месте (только GNU awk).

  • $1 == g{save=$4; next}

    Если мы сталкиваемся с существующим определением группы g в файле сохраняем членов группы (четвертое поле) в переменной save а затем пропустите остальные команды и перейдите к next линия.

    Здесь, внутри сценария awk, $1 а также $4 являются переменными awk, представляющими первое и четвертое поля в строке. Эти переменные полностью отделены и не связаны с переменными оболочки $ а также $4 который будет представлять аргументы сценария оболочки.

  • print

    Для всех остальных строк в /etc/groupмы просто печатаем их как есть.

  • ENDFILE{print g, "x", id, save}

    После достижения конца /etc/groupпечатаем новое определение группы g с идентификатором группы id и члены группы save, (Для стандартного awk мы используем END вместо ENDFILE.)

  • OFS=:

    Это говорит awk для использования : в качестве разделителя полей на выходе.

@John1024 имеет хороший ответ для ручного редактирования текстового файла /etc/group, хотя я подозреваю, что у него может быть проблема, не повреждающая группу, в которой есть участники:

docker:x:1001:bob,alice

Кроме того, в большинстве современных систем есть пара файлов, связанных с группами: / etc / group и /etc/gshadow.

Если поставленная задача - настоящая задача системного администратора, рассмотрите возможность использования уже имеющихся инструментов для управления файлами, относящимися к группам: groupadd а также groupmod,

Вот попытка:

#!/usr/bin/env bash

if [[ $# -ne 2 ]]; then
  echo "Usage: $(basename $0) <groupname> <groupid>" 1>&2
  exit 1
fi

set -e

[[ $EUID -eq 0 ]] || exec sudo "$0" "$@"

type groupadd &> /dev/null || PATH=/sbin:/usr/sbin:"$PATH"

# Add the group if it's not already present
#
grep -q "^$1:" /etc/group || groupadd -g "$2" "$1"

# Edit the group if it does not have the desired gid
# (See groupmod(8) for implications of a gid change here -
#  note that it will *not* change files' group ownerships
#  out in the system.)
#
grep -q "^$1:[^:]*:$2:" /etc/group || groupmod -g "$2" "$1"

Редактировать: более простая версия без проверки запуска от имени root или попытки использовать sudo, а также более простая строка интерпретатора, предполагающая, что bash доступен на /bin/bash в системе.

#!/bin/bash

if [[ $# -ne 2 ]]; then
  echo "Usage: $(basename $0) <groupname> <groupid>" 1>&2
  exit 1
fi

set -e

grep -q "^$1:" /etc/group || groupadd -g "$2" "$1"
grep -q "^$1:[^:]*:$2:" /etc/group || groupmod -g "$2" "$1"

Если сохранено как groupedit.sh и сделал исполняемым, запустил как root напрямую или через

$ sudo ./groupedit.sh

Команды groupadd / groupmod одинаковы, только без комментариев первой версии.

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