How to get user's name from uid

With GNU id, you can do:

id -un -- "$cheruid"

That will query the account database (whether it's stored in /etc/passwd, LDAP, NIS+, a RDBMS...) for the first user name with that uid.

Generally, there's only one user name per uid, but that's not guaranteed, the key in the user account database is the username, not user id.

If you want to know all the user names for a given uid, you can do:

getent passwd | ID=$cheruid awk -F: '$3 == ENVIRON["ID"] {print $1}'

But that may not work for some account databases that are not enumerable (as sometimes the case for large LDAP-based ones).


$ printf 'User is %s\n' "$( getent passwd 1001 | cut -d : -f 1 )"
User is myself

(there is a myself user with UID 1001 on my system)

This would query the passwd database for the given UID, strip out the username from that response and use the result as an argument to printf. This would not work on macOS.

To catch unknown UIDs:

$ printf 'User is %s\n' "$( { getent passwd 1001 || echo 'UNKNOWN USER'; } | cut -d : -f 1 )"
User is myself
$ printf 'User is %s\n' "$( { getent passwd 1002 || echo 'UNKNOWN USER'; } | cut -d : -f 1 )"
User is UNKNOWN USER

As a script taking any number of UIDs on the command line (with slightly altered output):

#!/bin/sh

for uid do
    printf 'User with UID %d is %s\n' "$uid" \
        "$( { getent passwd "$uid" || echo 'NOT KNOWN'; } | cut -d : -f 1 )"
done

Testing (this would go through some service accounts' UIDs on my OpenBSD system):

$ sh ./script.sh {110..115}
User with UID 110 is _sndiop
User with UID 111 is NOT KNOWN
User with UID 112 is _syspatch
User with UID 113 is NOT KNOWN
User with UID 114 is NOT KNOWN
User with UID 115 is _slaacd

Help with the original shellscript

The test in the if statement is causing the problem. I suggest the following shellscript,

#!/bin/bash

read -p "donner l UID " cheruid

 if [ "$(grep -w "^$cheruid" /etc/passwd)" != "" ]
 then
    grep -w "$cheruid" /etc/passwd | cut -d ":" -f "1" | xargs echo "user is : "
else
    echo "user not found"
fi

Edit1: I added a ^ in the test to only look for matches at the beginning of the line.

Edit2: since : is a separator, you can remove it and everything after, and use the result directly in the echo line, if accepted in the test, and simplify the shellscript to

#!/bin/bash

read -p "donner l UID " cheruid

cheruid=${cheruid%%:*}
user=$(grep -wo "^$cheruid" /etc/passwd)

if [ "$user" != "" ]
then
    echo "user is : $user"
else
    echo "user not found"
fi

This helps you make a good bash shellscript.

Efficient and more general method to find user IDs with id

If you want an efficient way to check if a particular user name exists, <test-name>, you can use id, as indicated in another answer to your question by Stéphane Chazelas:

id -un -- <test-name>

for example

id -un -- mehdi

id will find not only user IDs stored in /etc/passwd but also those managed and stored in other ways, for example LDAP, which is common in professional server systems as commented by Matteo Italia.


If you want to scan all users

  • system users, in many linux systems with user numbers < 1000

  • 'human' users, in many linux systems with user numbers >= 1000

  • and assuming that all users have number < 2000 (modify if you need)

you can use the following bash one-liner, which uses a loop with id,

for ((i=0;i<2000;i++));do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$i: $name" ;fi;done

If you want to see only the 'human' users and assume that no user ID number is skipped (no deleted user), the following bash oneliner is very fast,

i=1000;while true;do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$name" ;else break;fi;i=$((i+1));done

but it is more reliable to assume that some ID numbers may be skipped (deleted users),

for ((i=1000;i<2000;i++));do name=$(id -un $i 2>/dev/null);if [ $? -eq 0 ];then echo "$i: $name" ;fi;done

There are also users and who which print the user names of users currently logged in to the current host.

Tags:

Linux

Shell

Bash