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

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 и, следовательно, автоматически отфильтровывается как все другие нечеловеческие учетные записи пользователей.
миша