在/ etc / group文件中修改正确的组名和ID

时间:2017-08-29 21:47:29

标签: linux bash sh passwd etcpasswd

我将2个parms传递给bash脚本。第一个parm是group,第二个parm是groupID。 我想编写一个bash脚本来检查/etc/group中是否存在组。 如果不存在,那么脚本应该将组和gid添加到/etc/group。 如果存在则它应该与gid匹配第二个参数。如果gid与第二个参数不匹配,那么它应该用第二个parm覆盖gid。

简而言之,我传递给脚本的组名和gid应该在/ 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 个答案:

答案 0 :(得分:1)

我相信这段代码符合您的需求并且更简单:

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

该问题表明即使该组已存在,您也希望更新组ID。这里的代码有这个功能。

工作原理:

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

    这将删除组$1的现有定义(如果存在)。

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

    这会使用正确的组ID添加组$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"

    这使用shell变量$1$2来定义两个awk变量gid

  • -F:

    这告诉awk我们的字段分隔符是:

  • -i inplace

    这告诉awk就地修改文件(仅限GNU awk)。

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

    如果我们在文件中遇到组g的现有定义,请将组成员(第四个字段)保存在变量save中,然后跳过其余命令并跳转到{{ 1}}行。

    这里,在awk脚本中,next$1是表示该行上第一个和第四个字段的awk变量。这些变量完全独立且与shell变量$4$无关,它们代表shell脚本的参数。

  • $4

    对于print中的所有其他行,我们只是按原样打印它们。

  • /etc/group

    在到达ENDFILE{print g, "x", id, save}的末尾后,我们会打印组/etc/group的新定义,其中包含组ID g和组成员id。 (对于标准awk,我们使用END代替ENDFILE。)

  • save

    这告诉awk使用OFS=:作为输出的字段分隔符。

答案 1 :(得分:1)

@ John1024对手动编辑文本文件/ etc / group有一个很好的答案,虽然我怀疑它可能有一个问题,不会损坏一个有成员的组:

docker:x:1001:bob,alice

此外,大多数当前系统都有一对与组相关的文件:/ etc / group和/ etc / gshadow。

如果手头的任务是真正的系统管理员,请考虑使用现有的工具来管理与群组相关的文件:groupaddgroupmod

这是一次尝试:

#!/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命令是相同的,只是没有第一个版本的注释。