-1

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

2 回答 2

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:"

    这添加了$1具有正确组 ID 的正确组定义。

  • { ... } &&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,然后跳过其余命令并跳转到该next行。

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

  • print

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

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

    到达末尾后,我们打印带有组 ID和组成员/etc/group的组的新定义。(对于标准 awk,我们使用 END 代替 ENDFILE。)gidsave

  • OFS=:

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

于 2017-08-29T22:31:18.093 回答
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,以及一个更简单的解释器行,假设/bin/bash系统上可以使用 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 命令是一样的,只是没有第一个版本的注释。

于 2017-08-29T22:44:59.827 回答