Linux show user names

How can I list all user names and/or home directories?

But I use it in a script that will be deployed on others’ machines and maybe on those machines they don’t call it home (e.g. myHome). So I want to generalize it to ls -l ~ . But it just lists my user’s home directory instead of all users’ home directories (basically I want to get a list of the users’ names on the machine). How can I generalize it?

There is in fact, no guarantee that all users’ home directories are subdirectories of any one directory.

@hobbs or that they even exist until the user logs in. This is one of those apparently simple issues that gets complex really quickly.

Keep in mind that ~ is generally the equivalent of /home/user , not of /home or /home/* (which seem to be closer to your intention).

@EightBitTony: . nor is there any guarantee that the home directory exists at all. For example, on my Ubuntu install, several system users (including nobody ) have their home directory set to /nonexistent , which, obviously, does not exist. (Of course, those users also have their password hash set to * and their shell set to /usr/sbin/nologin or /bin/false , so they really can’t log in in the normal sense to begin with.)

On the other hand, an (old school) NFS server might serve home directories for users that are not known by name to its OS.

4 Answers 4

Many systems have a getent command to list or query the content of the Name Service databases like passwd , group , services , protocols .

Would list the home directories (the 6 th colon delimited field) of all the users in databases that can be enumerated.

The user name itself is in the first field, so for the list of user names:

(note that it doesn’t mean those users can login to the system or their home directory have been created, but that they are known to the system, they can be translated to a user id).

For databases that can’t be enumerated, you can try and query each possible user id individually:

(here assuming uids stop at 65535 (some systems support more) and a shell that supports zsh’s form of brace expansion). But you wouldn’t want to do that often on systems where the user database is networked (and there’s limited local caching) like LDAP, NIS+, SQL. as that could imply a lot of network traffic (and load on the directory server) to make all those queries.

That also means that if there are several users sharing the same uid, you’ll only get one entry for each uid, so miss the others.

Читайте также:  Zabbix агент linux настройка

If you don’t have getent , you could resort to perl :

perl -le 'while (@e = getpwent) ' 

for getent passwd ( $e[0] for the user names), or:

for getent passwd with the same caveats.

In shells, you can use ~user to get the home directory of user , but in most shells, that only works for a limited set of user names (the list of allowed characters in user names supported for that ~ expansion operator varies from shell to shell) and with several shells (including bash ), ~$user won’t work (you’d need to resort to eval when the name of the user is stored in a variable there). And you’d still have to find a way to get the list of user names.

Some shells have builtin support to get that list of usernames.

  • bash : compgen -u would return the list of users in databases that can be enumerated.
  • zsh : the $userdirs associative array maps user names to their home directory (also limited to databases that can be enumerated, but if you do a ~user expansion for a user that is in a non-enumerable database, an entry will be added to $userdirs ). So you can do:

The challenge for the OP will be knowing if getent is going to be there, which I guess to some extent depends on the scope of their ‘others machines’.

@seaturtle, perl -le ‘while (@e = getpwent) ‘ works fine on macOS.

@FloHe, those are user names. Most users on Unix systems are special system users whose life is dedicated to running system services. getent passwd shows you the user database. The first field is the user name, the 6th field is the users home directory.

A better way to list user home directories, is to parse /etc/passwd and extract them from there, and not make any assumptions about where they may be.

And judging by your second comment, you actually want the user names, not their home directories, in which case, /etc/passwd is a better choice anyway. Note that some Linux / UNIX machines will have other user authentication mechanisms configured (e.g. LDAP), and so ultimately, your query is more complex than you might first imagine, but /etc/passwd is a good place to start.

Yes, getent is always better than parsing /etc/passwd (it addresses the concern with “other user authentication mechanisms”).

@Kusalananda The problem with a getent solution is it assumes the data source can be enumerated, and not just queried for a specific value. That’s detailed in Stéphane Chazelas answer to this question, but I though I’d add a comment for anyone skimming over this page.

The short answer:

The medium answer: Since you’re using bash , you can list all possible completions for ~ using compgen -A user . That’s such a common usage, it can be abbreviated compgen -u . As a shell builtin, compgen does not have its own man page. Instead see bash(1) for documentation and read the section on Programmable Completion.

A more thorough alternative

If you’re extremely concerned about portability, you might not even be able to rely on other machines having bash . In that case, do this:

(getent passwd || dscl . -ls /Users dsAttrTypeNative:homeDirectory || nidump passwd || cat /etc/passwd) 2>/dev/null | cut -d: -f6 

Explanation The long answer tries everything, so it will work on pretty much any UNIX system, regardless of whether it uses the newer /etc/nsswitch.conf (both GNU/Linux and BSD come with getent ), the traditional UNIX passwd flat file, MacOS’s Directory Services¹ ( dscl ), or even the older, cat-themed MacOS X releases and NeXTSTEP ( nidump ).

Simplicity But, how portable do you need? Unix has many ways of doing things and sometimes simpler suffices. If you have to pick one, I’d recommend getent passwd | cut -d: -f6 for shell scripts.²

Footnote ¹: I haven’t used MacOS in a bit, so if someone can confirm for me that I got the syntax right (and the output doesn’t include any stray colons that would mess up cut ), that’d be great. Thanks.

Footnote ²: What I recommend and what I do may differ. Personally, I’ll more often use the traditional cut -d: -f1 /etc/passwd at the command line. After decades of repetition, my fingers can type it while my mind is working on other things.

Источник

How to List Users in Linux

Have you ever wanted to list all users in your Linux system or to count the number of users in the system? There are commands to create a user, delete a user, list logged in users, but what is the command to list all users in Linux?

This tutorial will show you how to list users in Linux systems.

Get a List of All Users using the /etc/passwd File #

Local user information is stored in the /etc/passwd file. Each line in this file represents login information for one user. To open the file you can either use cat or less :

Each line in the file has seven fields delimited by colons that contain the following information:

  • User name.
  • Encrypted password ( x means that the password is stored in the /etc/shadow file).
  • User ID number (UID).
  • User’s group ID number (GID).
  • Full name of the user (GECOS).
  • User home directory.
  • Login shell (defaults to /bin/bash ).

If you want to display only the username you can use either awk or cut commands to print only the first field containing the username:

root daemon bin sys sync . . sshd vagrant jack anne 

Get a List of all Users using the getent Command #

The getent command displays entries from databases configured in /etc/nsswitch.conf file, including the passwd database, which can be used to query a list of all users.

To get a list of all Linux userr, enter the following command:

As you can see, the output is the same as when displaying the content of the /etc/passwd file. If you are using LDAP for user authentication, the getent will display all Linux users from both /etc/passwd file and LDAP database.

You can also use awk or cut to print only the first field containing the username:

Check whether a user exists in the Linux system #

Now that we know how to list all users, to check whether a user exists in our Linux box we, can simply filter the users’ list by piping the list to the grep command.

For example, to find out if a user with name jack exists in our Linux system we can use the following command:

If the user exists, the command above will print the user’s login information. No output that means the user doesn’t exist.

We can also check whether a user exists without using the grep command as shown below:

Same as before, if the user exists, the command will display the user’s login information.

If you want to find out how many users accounts you have on your system, pipe the getent passwd output to the wc command:

As you can see from the output above, my Linux system has 33 user accounts.

System and Normal Users #

There is no real technical difference between the system and regular (normal) users. Typically system users are created when installing the OS and new packages. In some cases, you can create a system user that will be used by some applications.

Normal users are the users created by the root or another user with sudo privileges. Usually, a normal user has a real login shell and a home directory.

Each user has a numeric user ID called UID. If not specified when creating a new user with the useradd command, the UID will be automatically selected from the /etc/login.defs file depending on the UID_MIN and UID_MAX values.

To check the UID_MIN and UID_MAX values on your system, you can use the following command:

grep -E '^UID_MIN|^UID_MAX' /etc/login.defs
UID_MIN 1000 UID_MAX 60000 

From the output above, we can see that all normal users should have a UID between 1000 and 60000. Knowing the minimal and maximal value allow us to query a list of all normal users in our system.

The command below will list all normal users in our Linux system:

vagrant:x:1000:1000:vagrant. /home/vagrant:/bin/bash jack:x:1001:1001. /home/jack:/bin/bash anne:x:1002:1002:Anne Stone. /home/anne:/bin/bash patrick:x:1003:1003:Patrick Star. /home/patrick:/usr/sbin/nologin

Your system UID_MIN and UID_MIN values may be different so the more generic version of the command above would be:

eval getent passwd <$(awk '/^UID_MIN/ ' /etc/login.defs)..$(awk '/^UID_MAX/ ' /etc/login.defs)>

If you want to print only the usernames just pipe the output to the cut command:

eval getent passwd <$(awk '/^UID_MIN/ ' /etc/login.defs)..$(awk '/^UID_MAX/ ' /etc/login.defs)> | cut -d: -f1

Conclusion #

In this tutorial, you learned how to list and filter users in your Linux system and what are the main differences between system and normal Linux users.

The same commands apply for any Linux distribution, including Ubuntu, CentOS, RHEL, Debian, and Linux Mint.

Feel free to leave a comment if you have any questions.

Источник

Оцените статью
Adblock
detector