Shell Script to Get List of Defined Users on Linux

Finding linux users with a bash script

To print and read an argument from terminal, you should use echo and then use read commane and then call it with dollar-sign, finally the script know what you want.
for example:

echo "Enter UserName: "
read User_Name

here is the correct form of your code:

echo "Enter the Username: "
read User_Name
cut -f 1 -d: /etc/passwd | grep -q $User_Name
if [ $? -eq 0 ];
then
echo "User $User_Name FOUND"
else
echo "User NOT FOUND!"
fi

Tips:

cut -f 1 -d  #cut the first column of the passwd list
grep -q # find username and do not write anything to standard output in terminal.

if [ $? -eq 0 ] #in linux terminal when we want to know whether the previous command is executed correctly we use $? and the output must be 0. and - eq means equal to 0. and when we use that, it means if previos command (grep the username) executed correctly and the username was found, then run next step and print it found.

Script to get List of logged in users

Try doing this in single one awk statement:

who | awk '{print "The user " $1 " is on " $2}'

By doing that many piping, you are sending first one's input as another ones output. Hence you are losing previous data and at last only the output of who | awk '{print $2}' is coming out.

How do I list the functions defined in my shell?

declare -F

Function names and definitions may be listed with the -f option to the
declare builtin command (see Bash Builtins). The -F option to declare
will list the function names only
(and optionally the source file and line number).

Bash Reference Manual

How do I get the current user's username in Bash?

On the command line, enter

whoami

or

echo "$USER"

Script to filter users

You don't need to grep the password file, cut is enough:

cut -f1 -d ":" /etc/passwd

... will give you the list of users.

With GNU grep's -f option, you can use that list as a file of words to grep the input (your echo command):

#/bin/bash
grep -F -w -o -f <(cut -f1 -d ":" /etc/passwd)

The -o option outputs the part of the line that matches the word list specified by the -f option (rather than the full line of input).

The <(...) syntax is Bash's process substitution. The result of the command is provided as a file, which keeps you from storing the list of users in a temporary file.

List all the users logged in a specific group

In the general case, this is a painful exercise. I've seen password and group files in production use that defy logic — but work.

For sake of concrete example, let's suppose you're interested in the logged-in members of the group student.

Now, the entry in the group database (/etc/group file, plus network resources) for a named group such as student may or may not have any members listed. That doesn't necessarily mean there are no members in the group, though. Each entry in the password database (/etc/passwd file, plus network resources) has a group number assigned, and the group number might be the same as the group number for group student, in which case that user belongs to the group too.

However, we're not done yet. Suppose the entry in the group database reads:

student:x:2971:newton,einstein,socrates,plato

There might be other entries in the group database such as:

student_2020:x:2971:able,cain,adam,eve

Because this entry uses the same group number as group student, anyone who is listed in the student_2020 entry is functionally a member of group student — the o/s kernel uses the number, not the name, to determine groups.

There can be sound reasons for splitting up group file entries; historically at least, some programs ran into problems if the list of names is too long. That's bad programming, but when it is the system-provided software that does the crashing, you avoid triggering the crash. Hence the multiple entries.

You can end up with multiple entries with different group numbers for the same group name (really confusing!) or with multiple names for the same group number (as above) or with multiple entries with the same group number and name. It can be hit'n'miss as to what gets reported for any given name or number.

You can run into analogous problems in password files. For example, multiple user names all with the same user number is sometimes used to allow multiple people root access (their user number is 0) but each has a separate password so some tracking is feasible. However, it is generally better to use sudo these days — it was not always available, though. Occasionally, there'll be a mistake and the same user name will appear twice with different user numbers. Normally, the first entry in the file is used, but it can be confusing (at best).

However, it is not clear which programs you can use to analyze these issues, or derive a definitive answer about what is what. If you search for the group by name (getgrnam() in C), then you typically get the first entry that matches that name (but it isn't necessarily clear whether that entry came from the network or the local file system). If you search for the group by number (getgrgid() in C), then you typically get the first entry that matches that number. However, if you scan the entire database with setgrent() plus repeated getgrent() plus endgrent() (optional), you might see all sorts of entries.

As a case in point, I can run this code on my Mac:

#include <grp.h>
#include <stdio.h>

int main(void)
{
struct group *grp;
while ((grp = getgrent()) != 0)
{
printf("%5d %-15s", grp->gr_gid, grp->gr_name);
char **mem = grp->gr_mem;
char *pad = " -- ";
while (*mem != 0)
{
printf("%s%s", pad, *mem++);
pad = ", ";
}
putchar('\n');
}
return(0);
}

When I do that and pipe the output through sort -n, I get (in parts):

   -2 nobody         
-2 nobody
-1 nogroup
-1 nogroup
0 wheel -- root
0 wheel -- root
1 daemon -- root
1 daemon -- root
2 kmem -- root
2 kmem -- root
3 sys -- root
3 sys -- root
4 tty -- root
4 tty -- root
5 operator -- root
5 operator -- root
6 mail -- _teamsserver
6 mail -- _teamsserver
7 bin
7 bin

16 group
16 group
20 staff -- root
20 staff -- root, informix, anonymous, supernumerary
24 _networkd
24 _networkd

Why the double entries? Well, there's a file /etc/group which contains one set of entries — for example:

staff:*:20:root

There is also a database, Open Directory, that is consulted. Indeed, the first lines of the /etc/group file on a Mac are comment lines (comments are not usually supported on other o/s) that read:

##
# Group Database
#
# Note that this file is consulted directly only when the system is running
# in single-user mode. At other times this information is provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional information about
# Open Directory.
##

There's a similar spiel at the top of the /etc/passwd file. The Open Directory entry for staff lists 3 additional users. What's curious is that when I run id, I'm also in group staff:

uid=501(jleffler) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),204(_developer),399(com.apple.access_ssh),701(com.apple.sharepoint.group.1),100(_lpoperator),702(com.apple.sharepoint.group.2)

My name isn't even listed in /etc/passwd; it only appears in the Open Directory portion of the database.

And my name is only listed explicitly against groups 204 and 399 in the groups database; it is given group 20 in the password database; I'm not sure how groups 12, 61, 100, 701, 702 are associated with my user ID. (And it is news to me that I don't know this — sometimes answering a question is educational for more people than the one who asked the question.)

So, as I noted at the start, it is not straight-forward to find the answer to your question.

If you scan the password database and groups database, you can get a reasonable approximation to the information you need, but you may never get the full answer unless you explore the controls on your platform.

The answer by Abhishek Keshhri suggests there is a (Linux-specific? — not on macOS, anyway) command getent that can be used to analyze the group database (and probably the user or password database, and maybe others too). There are Open Directory tools on macOS to analyze the password and group databases on macOS. You don't have to write and compile C code (but the code shown isn't rocket science).

How can we get list of non-system users on linux?

You need to get all users whose gid is greater than or equals 1000. Use this command for that:

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

If you want system users (gid<1000) it will be:

awk -F: '($3<1000){print $1}' /etc/passwd


Related Topics



Leave a reply



Submit