Изменение правильного имени группы и идентификатора в файле /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
определить две переменные awkg
а также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 одинаковы, только без комментариев первой версии.