Список всех пользователей-людей


19

Как я могу перечислить всех пользователей-людей, которых я создал? Я пытался, cat /etc/passwdи это просто перечисляет много вещей.

Ответы:


18

У пользователей-людей 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).


15

Это делает в значительной степени то, что делает принятый ответ , только одной командой вместо трех:

awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}' /etc/passwd

И благодаря Карелу в комментариях nobodyпользователь тоже отфильтровывается.


@ Карел Да, может быть. Вместо того, чтобы фильтровать по UID, я отфильтровываю это имя пользователя явно. Может быть причина того, что у легитимного пользователя такой высокий UID ... Кто знает;)
Оли

9

Мне лично нравится использовать только:

ls /home

Следует признать, что это не список пользователей, а список их домашних каталогов. В настоящее время существующие пользователи в системе будут иметь домашние каталоги /home, но вы также можете увидеть домашние каталоги прошлых пользователей, которые были удалены.

Это работает для моих целей и может работать для вас. Например, если вы хотите удалить учетную запись пользователя, которая больше не существует ( nonexistent-user), и выполните команду

sudo deluser nonexistent-user

он просто скажет вам, что этого пользователя не существует.


+1 Этот способ прост, это то, что на самом деле делают большинство опытных пользователей, и я думаю, что он не менее надежен, чем методы, которые проверяют диапазон UID. Кажется, менее вероятно, что пользователь-человек будет иметь домашний каталог снаружи /home(который не имеет символической ссылки /home), чем то, что пользователь-человек будет иметь UID менее 1000 (в конце концов, это самый распространенный способ удержания диспетчера отображения от списка пользователь на экране входа в систему, что иногда может быть сделано для пользователя). Единственный, относительно незначительный недостаток здесь - это lost+foundто, что будет перечислено в системах с отдельными /homeразделами.
Элия ​​Каган

Небольшая проблема, однако: что произойдет, если пользователь был создан с useradd --no-create-home username?
Сергей Колодяжный

@ Сергей Я думаю, что все сводится к неоднозначности в описании проблемы. Действительно ли учетная запись без домашнего каталога представляет человека-пользователя? На практике такие учетные записи обычно - хотя и не всегда - используются для узкоспециализированных задач (как правило, людьми с собственными отдельными учетными записями) или для пользователей, намеревающихся получить доступ к системе только через определенные ограниченные службы. Конечно, есть другой вариант использования для useradd --no-create-home- домашний каталог может уже существовать или может быть создан вскоре после этого - но ls /homeметод отлично работает для этих случаев.
Элия ​​Каган

4

Хотя это может показаться четкой идеей, на самом деле в смысле человеческого пользователя существует двусмысленность . Является ли учетная запись пользователя преднамеренно скрытой от экрана входа в систему, потому что она используется только в специализированных целях (но для людей) человеком-пользователем? Как насчет 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что-то, кроме места для домашних каталогов пользователей, этот метод будет не дает надежного выхода.)

Упрощение проверки UID

Если вы решите использовать метод, который проверяет идентификаторы пользователей, чтобы убедиться, что они находятся в вероятном диапазоне для учетных записей, представляющих людей, как в принятом ответе или ответе Оли , то я предлагаю это для краткости:

getent passwd | grep -oP '^[^:]+(?=:x:\d{4}:)'

Это использует регулярное выражение Perl ( -P), чтобы показать:

  • текст в начале строки ( ^), не содержащий :s ( [^:]+) - это первое поле, как :и разделитель полей вpasswd
  • предшествует, но не включает ( (?= )) поле пароля x- так должно быть всегда x, поскольку в Ubuntu хеши паролей хранятся в shadowбазе данных, а не в общедоступной passwdбазе данных
  • и поле UID, состоящее ровно из 4 цифр ( :\d{4}:).

Таким образом, это значительно более короткий и несколько более простой вариант метода в принятом ответе . (Описанная там техника тоже отлично работает, и она имеет преимущество в том, что она переносима на не-GNU / Linux системы, которые grepне поддерживают -P.)

Пересматривая «человеческий» диапазон UID

Если вы хотите использовать очень высокие идентификаторы 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 *.
Муру

Я согласен с вами в том, что дома ненадежны (для меня это бесполезно, смотрите мой ответ). Я просто говорю, что если вы собираетесь проповедовать о стиле, ожидайте придирки.
Муру

@muru Я вижу, как мои оригинальные фразы могут ввести в заблуждение людей, которые думают, что избегать синтаксического анализа lsобычно связано со стилем. Второй пункт о «неудовлетворительном выводе» охватывал проблему, но она появится в следующем разделе. Я хотел бы уточнить, почему разбор lsявляется подходящим в этой ситуации . Несмотря на то, что они cd /home; getent passwd *принимают форму, часто указывающую на более разумный подход, я избегал ее, чтобы не заставить читателей поверить, что содержимое /homeкаталогов со странными добавленными записями, не соответствующими реальным пользователям, все же можно как-то использовать как руководство к тому, что пользователи существуют.
Элия ​​Каган

1

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}'


1
Хотя иногда это удобно, это не помогает в некоторых относительно распространенных сценариях. Например, в моей минимальной системе Ubuntu 15.04 (установленной из mini.isoи без менеджеров дисплея или X11) у меня есть одна учетная запись пользователя - но /var/lib/AccountsService/usersэто пустой каталог. Я ожидаю, что это также не будет работать при установке Ubuntu Server из коробки. Кроме того, когда это работает, оно делает это с несколько ограниченным представлением о том, что делает учетную запись пользователя «человеческой»: создание пользователя useradd, даже без --system него, не создает файл в AccountsService/users.
Элия ​​Каган

1

Присоединяясь к вечеринке, я наблюдаю за сетевыми системами, использующими LDAP, с домашними каталогами снаружи /homeи UID (из-за сбоя скриптов) в миллионах. Поэтому ни один из текущих ответов не работает. Тест, который работает для меня, проверяет, есть ли у пользователя действительная оболочка для входа. Действительной оболочкой является та, которая указана в /etc/shells. Самая простая форма:

getent passwd | grep -wFf /etc/shells

Файл может содержать комментарии (или пустые строки), поэтому может потребоваться отфильтровать их:

getent passwd | grep -wFf <(grep '^/' /etc/shells)

+1 Это может быть самый надежный подход, предложенный до сих пор. Хотя он имеет недостаток в показе root(который, вероятно, не следует рассматривать как пользователя-человека, поскольку люди обычно становятся корнями временно и для определенных целей, а не используют его для своей обычной работы), кажется, что это наименее вероятно, что потерпит неудачу в любым основным способом. Методы в других ответах ( в том числе и мой) могут не сработать, в зависимости от метода, если домашние каталоги не /home, другой мусор находится в /home, UIDs странных, или система не использует DM. Этот ответ работает очень хорошо во всех этих сценариях.
Элия ​​Каган

1

В системах 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. =)
анатолий техтоник

1
Вам не нужно этого делать, потому что никто не имеет UID 65534 и, следовательно, автоматически отфильтровывается как все другие нечеловеческие учетные записи пользователей.
миша
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.