Вопрос или проблема
Это было бы проще простого в PowerShell на Windows, но я не могу разобраться, как сделать это в оболочке. Я могу получить список групп с помощью groups bob
, например:
bob : bob tty dialout cdrom plugdev users kvm docker
И команда должна выглядеть так:
sudo usermod -aG tty,dialout,cdrom,plugdev,users,kvm,docker newbob
Я дошел до этого:
(groups bob)|cut -d ':' -f 2|xargs|cut -d ' ' -f 1-|sed 's/ /,/g'
что генерирует это:
bob,tty,dialout,cdrom,plugdev,users,kvm,docker
но когда я пытаюсь подставить это:
usermod -aG ((groups bob)|cut -d ':' -f 2|xargs|cut -d ' ' -f 2-) newbob
Я получаю:
bash: syntax error near unexpected token `('
Кроме того, это кажется очень неуклюжим.
Это немного менее неуклюже:
usermod -aG $(groups bob | awk '{for (i=3; ++i<NF;) printf "%s,", $i; print $NF}') newbob
Я не уверен, будет ли проблема с завершающей запятой, но по крайней мере должен быть перенос строки в конце, так что, вероятно, потребуется два print(f)
.
Вот более простая команда, которая дает вам список групп, к которым принадлежит пользователь, в виде строки, разделенной запятой:
$ groups bob | perl -pe 's/.*?: \S+ //; s/ /,/g'
bob,tty,dialout,cdrom,plugdev,users,kvm,docker
Флаги -pe
в Perl означают “pечатать каждую строку входного файла/данных после применения скрипта, заданного с помощью -e, к каждой строке”. А скрипт состоит из нескольких операций замены. Сначала мы заменяем все до первого :
, за которым следует пробел (.*?:
), и затем один или несколько непробельных символов (\S+
) на ничего, фактически удаляя все до второй группы. Затем мы просто заменяем все пробелы на ,
.
С этой командой вы теперь можете сделать:
sudo usermod -aG "$(groups bob | perl -pe 's/.*?: \S+ //; s/ /,/g')" newbob
Я не понимаю, зачем вы добавили xargs
, это здесь не нужно и бесполезно. И обратите внимание, что синтаксис для использования вывода команды – это $(command)
, поэтому ваш ((command))
не срабатывал.
Если вы будете часто делать это, возможно, стоит просто превратить это в небольшую функцию оболочки. Добавьте эти строки в ваш файл ~/.bashrc
:
change_groups(){
oldUser=$1
newUser=$2
groups=$(groups "$oldUser" | perl -pe 's/.*?: \S+ //; s/ /,/g')
usermod -aG "$groups" "$newUser"
}
Теперь откройте новое терминальное окно, и вы сможете просто запустить:
sudo change_groups bob newbob
Я думаю, вы имеете в виду оператор оценки?
usermod -aG $($(groups bob)|cut -d ':' -f 2|xargs|cut -d ' ' -f 2-) newbob
Ответ или решение
Для того чтобы добавить нового пользователя в те же группы, что и существующий, в Unix-подобных системах, мы можем воспользоваться командной оболочкой bash и соответствующими утилитами командной строки. Давайте рассмотрим процесс более подробно, исходя из предоставленного контекста.
Теория
В Unix-системах пользователи могут принадлежать к различным группам, что позволяет управлять правами доступа к ресурсам системы. Группы играют важную роль в управлении безопасностью и доступом, позволяя ограничивать или предоставлять доступ к файлам, программам и сервисам только определенным категориям пользователей.
Команда usermod
с параметром -aG
используется для добавления существующего пользователя в одну или несколько дополнительных групп без удаления из текущих групп. Параметр -a
означает "append" (добавить), а -G
— это список групп, к которым нужно добавить пользователя.
Пример
Давайте рассмотрим практический пример использования командной оболочки для выполнения этой задачи. Предположим, у нас есть существующий пользователь "bob", и мы хотим, чтобы новый пользователь "newbob" был добавлен в те же группы, что и "bob".
-
Получение списка групп текущего пользователя:
Для начала, мы используем команду
groups
для получения списка групп, к которым принадлежит пользователь "bob":groups bob
Вывод будет такой:
bob : bob tty dialout cdrom plugdev users kvm docker
Здесь нас интересуют имена групп после двоеточия.
-
Форматирование списка групп:
Далее, нам нужно обработать вывод команды, чтобы превратить его в формат, который можно передать в команду
usermod
. Конкретно, нам нужно убрать имя пользователя и оставить только группы в формате, разделённом запятыми.Наиболее эффективный способ сделать это — использование сочетания утилит shell, таких как
awk
,sed
, илиperl
. В представленном примере используется командаperl
:groups bob | perl -pe 's/.*?: \S+ //; s/ /,/g'
Этот скрипт удаляет всё до второго слова и заменяет пробелы на запятые, получая строку:
bob,tty,dialout,cdrom,plugdev,users,kvm,docker
Чтобы избежать включения самой первой группы, воспользуемся немного модифицированной конструкцией, которая исключает первую группу:
groups bob | sed 's/^.*: //' | sed 's/ \+/,/g'
Так мы получим нужный список групп без имени пользователя:
tty,dialout,cdrom,plugdev,users,kvm,docker
-
Добавление нового пользователя в группы:
Теперь передадим этот список через команду
usermod
:sudo usermod -aG $(groups bob | sed 's/^.*: //' | sed 's/ \+/,/g') newbob
Даная команда добавит пользователя "newbob" во все группы, в которых состоит "bob", без удаления их из уже существующих групп у пользователя "newbob".
Применение
Эту задачу можно упростить, если она выполняется часто, создав функцию в файле конфигурации, например, в .bashrc
или .bash_profile
. Добавьте в файл следующие строки:
Добавить_в_группы() {
лок_старый_пользователь=$1
лок_новый_пользователь=$2
лок_список_групп=$(groups "$лок_старый_пользователь" | sed 's/^.*: //' | sed 's/ \+/,/g')
sudo usermod -aG "$лок_список_групп" "$лок_новый_пользователь"
}
Теперь вы можете использовать так называемую команду для добавления пользователей в группы:
sudo Добавить_в_группы bob newbob
Этот подход автоматизирует процесс и избавляет от необходимости каждый раз вводить полные команды. Таким образом, вы снижаете вероятность ошибок и повышаете эффективность работы при частых повторениях подобных операций.
Заключение
Использование командной оболочки bash и утилит Unix позволяет гибко и эффективно управлять пользователями и их группами. Предложенный подход полностью автоматизирует задачу добавления групп, обеспечивая при этом максимальную точность и надежность. При этом функционал может быть легко встроен в повседневные рабочие процессы, обеспечивая регулирование прав доступа.