Как я могу перечислить всех пользователей-людей, которых я создал? Я пытался, cat /etc/passwd
и это просто перечисляет много вещей.
Как я могу перечислить всех пользователей-людей, которых я создал? Я пытался, cat /etc/passwd
и это просто перечисляет много вещей.
Ответы:
У пользователей-людей UID начинаются с 1000, так что вы можете использовать этот факт для фильтрации не-людей:
cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1
Это обрезает первое (имя пользователя) и третье (UID) поля, разделенные двоеточием /etc/passwd
, затем фильтрует результирующие строки, заканчивающиеся двоеточием и четырьмя цифрами, а затем обрезает первое (имя пользователя) поле из этого, оставляя вам список пользователи с UID от 1000 до 9999.
Если в вашей системе более девяти тысяч пользователей, это не удастся, но необходимо ограничить результат 4-значными UID, чтобы не перехватывать nobody
(UID 65534).
Это делает в значительной степени то, что делает принятый ответ , только одной командой вместо трех:
awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd
И благодаря Карелу в комментариях nobody
пользователь тоже отфильтровывается.
Мне лично нравится использовать только:
ls /home
Следует признать, что это не список пользователей, а список их домашних каталогов. В настоящее время существующие пользователи в системе будут иметь домашние каталоги /home
, но вы также можете увидеть домашние каталоги прошлых пользователей, которые были удалены.
Это работает для моих целей и может работать для вас. Например, если вы хотите удалить учетную запись пользователя, которая больше не существует ( nonexistent-user
), и выполните команду
sudo deluser nonexistent-user
он просто скажет вам, что этого пользователя не существует.
/home
(который не имеет символической ссылки /home
), чем то, что пользователь-человек будет иметь UID менее 1000 (в конце концов, это самый распространенный способ удержания диспетчера отображения от списка пользователь на экране входа в систему, что иногда может быть сделано для пользователя). Единственный, относительно незначительный недостаток здесь - это lost+found
то, что будет перечислено в системах с отдельными /home
разделами.
useradd --no-create-home username
?
useradd --no-create-home
- домашний каталог может уже существовать или может быть создан вскоре после этого - но ls /home
метод отлично работает для этих случаев.
Хотя это может показаться четкой идеей, на самом деле в смысле человеческого пользователя существует двусмысленность . Является ли учетная запись пользователя преднамеренно скрытой от экрана входа в систему, потому что она используется только в специализированных целях (но для людей) человеком-пользователем? Как насчет ubuntu
пользователя (UID 999) на live CD? И гостевые учетные записи в Ubuntu создаются на лету и уничтожаются после выхода из системы; они люди? Можно привести больше примеров.
Поэтому вполне уместно дать несколько неэквивалентных ответов. Решение Сэйдж Хамблин в бежать , ls /home
что люди на самом деле делают, и если вы не пишете сценарий, вероятно , вы должны просто использовать.
ls /home
более надежнымНо, возможно, у вас есть пользователи, которые были удалены, но чьи домашние каталоги все еще существуют /home
, и вы должны избегать их перечисления. Или, может быть, по какой-то другой причине вы должны убедиться, /home
что перечислены только те записи, которые соответствуют реальным счетам.
В этом случае я предлагаю прохождение имена все в /home
к getent
(для извлечения passwd
записей пользователей с этими именами), затем выделить и отобразить только поле имени пользователя (с grep
, sed
или awk
, в соответствии с вашими предпочтениями). Любой из них будет делать:
getent passwd $(ls /home) | grep -o '^[^:]*'
getent passwd $(ls /home) | sed 's/:.*//'
getent passwd $(ls /home) | awk -F: '{print $1}'
Это должно работать хорошо, так как у вас не должно быть учетных записей пользователей с пробелами или управляющими символами в их именах; не может, без перенастройки Ubuntu, чтобы позволить это ; и если вы это сделаете, у вас есть большие проблемы. Таким образом , обычные проблемы с разбором ls
являются неприменимыми. Но даже при том, что здесь все в порядке, если вы считаете замену команд ls
эстетически неприятной или просто вредной привычкой, вы можете предпочесть:
getent passwd $(basename -a /home/*) | grep -o '^[^:]*'
getent passwd $(basename -a /home/*) | sed 's/:.*//'
getent passwd $(basename -a /home/*) | awk -F: '{print $1}'
Они также не содержат пробелов и управляющих символов. Я предоставляю их только потому, что $(ls /home)
выглядит неправильно, даже когда это правильно, и, таким образом, теряет многих пользователей в неправильном направлении. В большинстве ситуаций есть реальные веские причины избегать синтаксического анализаls
, и в таких ситуациях анализ basename -a
обычно очень незначительный. В этой ситуации, однако, из-за ограничения на то, какие символы могут фактически встречаться в именах пользователей , они оба в порядке.
Я использую в getent
основном потому, что он принимает имена пользователей в качестве аргументов для ограничения своего вывода, а также потому, что он немного более универсален, чем /etc/passwd
проверка напрямую, если средства аутентификации и база данных паролей предоставляются сетевыми службами.
Этот метод имеет дополнительное преимущество по сравнению с ls /home
тем, что в системах с отдельным /home
разделом lost+found
обычно появляется в выходных данных ls /home
.
lost+found
появится, только если вызван пользователь (человек или нет) lost+found
, что маловероятно.ls /home
это нормально - вы знаете, что вам не нужен пользователь-пользователь lost+found
.Нечасто этот метод (в любом из вышеперечисленных вариантов) будет давать неудовлетворительный результат:
/home
или не существует вообще, это предполагает, но не подразумевает, что учетная запись не должна рассматриваться как представляющая пользователя. Этот метод выводит список пользователей только при наличии каталога с тем же именем в /home
./home
, которые на самом деле не являются домашними каталогами кого-либо, и они имеют то же имя, что и существующий пользователь, не являющийся человеком, или состоят из слов, разделенных пробелами, один или несколько из которых имеют одно и то же имя в качестве существующего пользователя, не являющегося человеком, - в вывод могут быть включены некоторые пользователи, не являющиеся людьми. getent
вызовов, поэтому разделение слов не приводит к ложному выводу. Но сложность не гарантируется; в основном, если вы используете /home
что-то, кроме места для домашних каталогов пользователей, этот метод будет не дает надежного выхода.)Если вы решите использовать метод, который проверяет идентификаторы пользователей, чтобы убедиться, что они находятся в вероятном диапазоне для учетных записей, представляющих людей, как в принятом ответе или ответе Оли , то я предлагаю это для краткости:
getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'
Это использует регулярное выражение Perl ( -P
), чтобы показать:
^
), не содержащий :
s ( [^:]+
) - это первое поле, как :
и разделитель полей вpasswd
(?=
)
) поле пароля x
- так должно быть всегда x
, поскольку в Ubuntu хеши паролей хранятся в shadow
базе данных, а не в общедоступной passwd
базе данных:\d{4}:
).Таким образом, это значительно более короткий и несколько более простой вариант метода в принятом ответе . (Описанная там техника тоже отлично работает, и она имеет преимущество в том, что она переносима на не-GNU / Linux системы, которые grep
не поддерживают -P
.)
Если вы хотите использовать очень высокие идентификаторы UID и проверить их nobody
явно, вы можете использовать метод в ответе Оли . Однако вы можете решить, следует ли считать пользователей с очень высокими идентификаторами UID людьми, или если они с большей вероятностью являются пользователями, не являющимися людьми специального назначения (например nobody
). На практике такие пользователи - кроме того - nobody
редки, так что на самом деле это призыв к суждению с вашей стороны.
Возможный компромисс - перечислить пользователей в диапазоне UID , которые фактически назначаются вновь созданным, не «системным» пользователям. Вы можете проверить это вadduser.conf
:
$ grep -E '^(FIRST|LAST)_UID' /etc/adduser.conf
FIRST_UID=1000
LAST_UID=29999
Вот два способа составить список пользователей, чьи UID варьируются от 1000 до 29999:
getent passwd | grep -oP '^[^:]+(?=:x:[12]?\d{4}:)'
getent passwd | awk -F: '999<$3 && $3<30000 {print $1}'
basename
это безобразно. Это не лучше чем ls
. Основная причина, по которой мы не анализируем, заключается в том, что эту работу можно выполнять другими инструментами гораздо безопаснее и аккуратнее, а не стилем. В этом случае оболочка: cd /home; getent passwd *
.
ls
обычно связано со стилем. Второй пункт о «неудовлетворительном выводе» охватывал проблему, но она появится в следующем разделе. Я хотел бы уточнить, почему разбор ls
является подходящим в этой ситуации . Несмотря на то, что они cd /home; getent passwd *
принимают форму, часто указывающую на более разумный подход, я избегал ее, чтобы не заставить читателей поверить, что содержимое /home
каталогов со странными добавленными записями, не соответствующими реальным пользователям, все же можно как-то использовать как руководство к тому, что пользователи существуют.
TL; DR : только пользователи-пользователи имеют SystemAccount = false
Еще один способ - выводить список при игнорировании root ls /var/lib/AccountsService/users/ | grep -v root
. Теперь есть причуды - gdm, экран приветствия / входа в систему (или, более формально, менеджер рабочего стола) также указан как пользователь. Так что просто из списка мы не можем сказать, является ли gdm человеком или нет.
Более эффективный и правильный подход - просмотреть файлы в этой папке и выяснить, какие пользователи указаны как имеющие SystemAccount=false
. Однолинейный сильфон достигает этого
grep SystemAccount=false /var/lib/AccountsService/users/* | awk -F '/' '{gsub(":","/");print $6}'
mini.iso
и без менеджеров дисплея или X11) у меня есть одна учетная запись пользователя - но /var/lib/AccountsService/users
это пустой каталог. Я ожидаю, что это также не будет работать при установке Ubuntu Server из коробки. Кроме того, когда это работает, оно делает это с несколько ограниченным представлением о том, что делает учетную запись пользователя «человеческой»: создание пользователя useradd
, даже без --system
него, не создает файл в AccountsService/users
.
Присоединяясь к вечеринке, я наблюдаю за сетевыми системами, использующими LDAP, с домашними каталогами снаружи /home
и UID (из-за сбоя скриптов) в миллионах. Поэтому ни один из текущих ответов не работает. Тест, который работает для меня, проверяет, есть ли у пользователя действительная оболочка для входа. Действительной оболочкой является та, которая указана в /etc/shells
. Самая простая форма:
getent passwd | grep -wFf /etc/shells
Файл может содержать комментарии (или пустые строки), поэтому может потребоваться отфильтровать их:
getent passwd | grep -wFf <(grep '^/' /etc/shells)
root
(который, вероятно, не следует рассматривать как пользователя-человека, поскольку люди обычно становятся корнями временно и для определенных целей, а не используют его для своей обычной работы), кажется, что это наименее вероятно, что потерпит неудачу в любым основным способом. Методы в других ответах ( в том числе и мой) могут не сработать, в зависимости от метода, если домашние каталоги не /home
, другой мусор находится в /home
, UIDs странных, или система не использует DM. Этот ответ работает очень хорошо во всех этих сценариях.
В системах Buntu обычные пользователи (то есть пользователи) имеют идентификаторы UID, начинающиеся с 1000, которые назначаются им последовательно при первом создании их учетных записей. Все это сводится к тому, что первая учетная запись, созданная в системе Buntu, имеет UID 1000. Следующая созданная учетная запись имеет UID 1001. И так далее, и тому подобное.
Итак, самый простой способ перечислить все учетные записи пользователей-людей, присутствующих в системе, на мой взгляд, это проверить, является ли третий столбец в /etc/passwd
файле, который содержит UID пользователя, больше или равен 1000 и меньше, скажем, 2000 (маловероятно, что на типичном настольном ПК будет более тысячи учетных записей, не так ли?):
$ awk -F$':' '{ if ($3 >= 1000 && $3 < 2000) print $1; }' /etc/passwd
nobody
. =)