Получить список пользователей в группе в FreeBSD

Вопрос или проблема

Как получить список имен пользователей, назначенных группе в FreeBSD 11.1?

Этот вопрос запрашивает список пользователей или список групп.

Этот вопрос запрашивает пользователей, которые являются членами нескольких конкретных групп.

➥ Но как просто запросить список пользователей, в данный момент назначенных единственной конкретной группе, такой как wheel?

Я предпочитаю решение в одной команде, если это возможно. Но если это невозможно, скрипт будет полезным и образовательным.

Вы можете выбрать пользователей с конкретной группой из списка всех пользователей, предоставленного утилитой pw:

pw usershow -P -a | grep groupname

Результат будет выглядеть примерно так:

Login Name: username1     #1024         Group: groupname          #1002
Login Name: username2     #1025         Group: groupname          #1002

Правильный способ показать всех пользователей в определенной группе в FreeBSD:

# pw groupshow groupname

Следуя системным скриптам, таким как getent, пользователи могут находиться в группе двумя способами: либо это их основная группа, определенная в /etc/passwd, либо у них есть она как вторичная группа в /etc/groups.

GROUPID=1000
sed -rn "s/^[^:]*:[^:]*:$GROUPID://p" < /etc/group | tr ',' '\n'
sed -rn "s/^([^:]*):[^:]*:[^:]*:$GROUPID:.*/\\1/p" < /etc/passwd

Это должно сработать хорошо. awk будет, вероятно, выглядеть лучше…

GROUPID=1000
awk -F: -v "g=$GROUPID" '{if ($3==g) print $1;}' /etc/passwd
awk -F: -v "g=$GROUPID" '{if ($3==g) print $4;}' /etc/group | tr ',' '\n'

https://www.cyberciti.biz/faq/linux-list-all-members-of-a-group/ содержит множество способов сделать это. Я лично предпочитаю метод членов. Но метод ниже является родным и работает хорошо.

$ grep 'grpup-name-here' /etc/group
$ grep 'ftponly' /etc/group
$ grep -i --color 'ftponly' /etc/group

Этот ответ предполагает, что вы используете исключительно переносимые идентификаторы групп и пользователей, определенные стандартом POSIX™.

  • Если вас интересует только явное членство в группе, т. е. утверждения «группа X содержит участников …», определенные через файл /etc/group, вы можете использовать:

    • Исключая сетевые учетные записи пользователей:
      pw group show operator # или groupshow
      
    • Включая пользователей из других источников базы данных, как это определено в /etc/nsswitch.conf:
      getent group family
      

    Любой из выводов можно отфильтровать в более читаемую форму:

    … | cut -d':' -f4 | tr ',' ' ' | fmt
    
  • Если вы хотите узнать о членстве в группе включая основную группу, как это определяется через 4е поле традиционного passwd текстового файла базы данных, вам нужно либо

    • обеспечить, чтобы все такие определения членства в группе были явно (и избыточно) зарегистрированы в /etc/group,
    • либо вывести эту информацию из доступных данных.

    Первый вариант не рекомендуется или не поддерживается. Второй вариант можно реализовать несколькими способами.

    • Напишите скрипт оболочки, например:
      #!/bin/sh -u
      #        name: members
      # description: показывать участников группы или ничего в случае неизвестных групп
      #  maintainer: J Doe <mailbox@host> # заполните в средах с несколькими администраторами
      getent group "${1:-}" | {
          # Определите числовой идентификатор группы и получите явных участников группы.
          # Примечание: переменные оболочки могут столкнуться с ограничением по размеру.
          IFS=':' read -r group_name group_password group_identifier group_members
      
          # Теперь найдите неявных участников группы, используя числовой идентификатор группы.
          getent passwd | grep "^..*:..*:..*:${group_identifier}:" | cut -d':' -f1
      
          # Поскольку предыдущая пайплайн выводит каждое имя пользователя на отдельной строке,
          # выводим `${group_members}` тоже по одной строке.
          [ "${group_members}" ] && printf '%s\n' "${group_members}" | tr ',' '\n'
      } | sort -u # | { tr '\n' ' ' ; printf '\n' ; } # если вы предпочитаете
      # EOF
      

      Или немного медленнее, так как вам нужно будет несколько раз запускать процесс (id):

      #!/bin/sh -u
      #        name: members
      # description: показывать участников группы, имя группы соответствует шаблону оболочки
      #  maintainer: B Bourque <mailbox@host> # заполните в средах с несколькими администраторами
      
      # В шаблонах оболочки звездочки расширяются в строки любой длины (включая 0).
      # Окружающие пробелы необходимы для привязки.
      expression="* ${1:?Ошибка: Укажите одно имя группы в качестве аргумента.} *"
      
      getent passwd | while IFS=':' read -r username remainder
      do
          # `id -G` получает все группы, к которым принадлежит пользователь,
          # включая основную группу, указанную в `passwd`.
          # Флаг `-n` разрешает числовые идентификаторы в текстовые представления.
          groups=" $(id -Gn ${username}) "
          # `##` означает «удалить самый большой префиксный шаблон».
          # Если строка становится пустой строкой в результате этой операции,
          # `[ "" ]` возвращает `false`, так что `||` («иначе») применяется.
          [ "${groups##${expression}}" ] || printf '%s\n' "${username}"
      done | sort
      # EOF
      

      Последняя реализация может быть полезной, если у вас есть имена групп, следующее определенному шаблону, т. е. departmentX, departmentY, departmentZ.
      Если вы хотите найти пользователей, принадлежащих к любой группе, вы можете вызвать скрипт как

      ./members.sh 'department*' # '…' чтобы подавить расширение в вызывающей оболочке
      
    • Если у вас установлены shells/bash, shells/zsh или другие богатые функции оболочки, вы можете выполнять операции с текстовыми файлами, используя подстановку процесса.
      Подстановка процесса является языковым конструкцией выбора, поскольку утилита join может обрабатывать не более одной трубы (- для стандартного ввода) в качестве параметра.
      Замените operator соответственно.

      join -t':' -1'1' -2'2' -a1 \
          <(getent group operator | cut -d':' -f3,4                 ) \
          <(getent passwd         | cut -d':' -f1,4 | sort -t':' -k2) \
          | cut -d':' -f3- | tr ',:' ' '
      
  • Имейте в виду, что группы UNIX не являются единственным способом предоставления возможностей.
    Например, файлы могут иметь ACL.
    Исполняемые файлы могут иметь установленный бит set-group-ID.

pw group show ftpgroup

ftpgroup:*:2001:

pw group show wheel

wheel:*:0:root,fred,carl

pw group show video

video:*:44:lightdm

pw user show ftp

ftp:*:2002:2001::0:0:PureFTP user:/nonexistent:/usr/sbin/nologin

pw user show carl

carl:$6$SDkXHtJyIp53egpl$XBg3cuem.RLW63Pa0E16Qw4hmc96lXFgC/fTwCSnDEgYE/OhairDv.mX193ToC6PaQfsp.NegsqEYMHSMxinE/:1003:1003::0:0:Carl
Dubak:/home/carl:/usr/local/bin/fish

pw user show fred

fred:$6$alWrCEOtGuU1Bx7t$oWXCNkP4t4yQVn5.0ZKuJqAtCNXkR5ywcdI0Guxqv3myDI.u/qrqUzBX7BW4jmwLFHDd00tCdyGt3A9Q6T4s4/:1002:1002::0:0:Fred
Finster:/home/fred:/usr/local/bin/fish

getent passwd {carl}

carl:$6$SDkXHtJyIp53egpl$XBg3cuem.RLW63Pa0E16Qw4hmc96lXFgC/fTwCSnDEgYE/OhairDv.mX193ToC6PaQfsp.NegsqEYMHSMxinE/:1003:1003:Carl
Dubak:/home/carl:/usr/local/bin/fish

getent passwd {fred}

fred:$6$alWrCEOtGuU1Bx7t$oWXCNkP4t4yQVn5.0ZKuJqAtCNXkR5ywcdI0Guxqv3myDI.u/qrqUzBX7BW4jmwLFHDd00tCdyGt3A9Q6T4s4/:1002:1002:Fred
Finster:/home/fred:/usr/local/bin/fish

id

id=0(root) gid=0(wheel) groups=0(wheel),5(operator)

id 1003

uid=1003(carl) gid=1003(carl) groups=1003(carl),0(wheel),5(operator)

id 1002

uid=1002(fred) gid=1002(fred)
groups=1002(fred),0(wheel),5(operator),145(webcamd)

id 5

uid=5(kmem) gid=65533(nogroup) groups=65533(nogroup)

id {operator}

uid=2(operator) gid=5(operator) groups=5(operator)

Ответ или решение

Чтобы получить список пользователей, назначенных на конкретную группу в FreeBSD, например, группу wheel, можно воспользоваться утилитой pw или просмотреть файлы /etc/passwd и /etc/group. В этой статье рассмотрим несколько методов, включая однокомандные решения и написание небольших скриптов для более сложных задач.

Получение списка пользователей группы с помощью pw

  1. Использование команды pw:
    Для получения списка членов конкретной группы, вы можете использовать следующую команду:

    pw groupshow wheel

    Эта команда выведет информацию о группе wheel, включая всех её членов. Результат будет похож на:

    wheel:*:0:root,fred,carl

    Здесь видно, что пользователи root, fred и carl являются членами группы wheel.

  2. Альтернативный способ с использованием getent:
    Если в вашей системе настроена поддержка NetService Switch (NSS), можно воспользоваться командой getent. Эта команда позволяет получить информацию о группах и пользователях из различных источников:

    getent group wheel

    Аналогично, результат будет содержать список членов группы:

    wheel:x:0:root,fred,carl

Список пользователей группы через файлы /etc/passwd и /etc/group

Если по какой-то причине вам не подходит метод с pw или getent, можно использовать и стандартные текстовые файлы.

  1. Определение идентификатора группы:
    Сначала нужно узнать UID (идентификатор группы) для группы wheel. Это можно сделать с помощью:

    grep '^wheel:' /etc/group

    Предположим, что вывод будет таким:

    wheel:*:0:

    Здесь 0 — это идентификатор группы.

  2. Поиск пользователей с указанным групповым UID:
    Теперь можно найти всех пользователей, используя этот идентификатор. Запустите следующие команды:

    Для поиска пользователей с ID 0 как основной группы:

    awk -F: -v "g=0" '{if ($3==g) print $1;}' /etc/passwd

    Для поиска вторичных членов группы wheel, можно использовать следующую команду:

    grep wheel /etc/group | cut -d':' -f4 | tr ',' '\n'

Написание скрипта для получения списка пользователей в группе

Если вам нужно автоматизировать процесс, Вы можете написать небольшой shell-скрипт. Например:

#!/bin/sh
# Скрипт для вывода пользователей в указанной группе

GROUP_NAME="$1"

if [ -z "$GROUP_NAME" ]; then
  echo "Укажите имя группы для поиска."
  exit 1
fi

echo "Пользователи группы $GROUP_NAME:"

# Получаем список членов группы
pw groupshow "$GROUP_NAME" | cut -d':' -f4 | tr ',' '\n'

# Получаем пользователей с этой группе
GROUP_ID=$(grep "^$GROUP_NAME:" /etc/group | cut -d':' -f3)

awk -F: -v "g=$GROUP_ID" '{if ($3==g) print $1;}' /etc/passwd

Сохраните этот скрипт, например, как list_group_members.sh, и сделайте его исполняемым:

chmod +x list_group_members.sh

Теперь вы можете вызвать его, передав название группы:

./list_group_members.sh wheel

Заключение

Теперь вы знаете несколько способов получения списка пользователей, относящихся к определённой группе в FreeBSD. Можно использовать команды pw, getent, а также анализировать системные файлы. Кроме того, написание скрипта позволяет упростить процесс и адаптировать его под ваши специфические нужды. Такой подход обеспечивает эффективность работы с пользователями на вашем сервере.

Оцените материал
Добавить комментарий

Капча загружается...