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.