Script to create a group and users in it

Hello again,

I’m writing a Script and I’m a little stuck.

I need ask user about a name to create a group, if that group already exists ask for another name. If not, write the name in a file.
Also I need to ask what users he want to add to that group and verify that users exists in the system.

I was using, while, If, and open to work with /etc/groups to verify if the group exist,

But I write, write and I’m still stuck.

Any tip for where should I start?

Tank you,
Seba.rvr

I’m writing a Script and I’m a little stuck.

I need ask user about a name to create a group, if that group already exists ask for another name. If not, write the name in a file.
Also I need to ask what users he want to add to that group and verify that users exists in the system.

I was using, while, If, and open to work with /etc/groups to verify if the group exist,

It would be better to use the “grp” module and its getgrnam function:

https://docs.python.org/3/library/grp.html#grp.getgrnam

That way it will (a) parse /etc/group for you and (b) work in
environments where /etc/group is not the whole story, for example a
networked setting where a NIS server provides users and groups to all
hosts.

Call getgrnam(group_name) with the group name. If it raises KeyError
then the group_name is unknown.

But I write, write and I’m still stuck.

Try the above approach. Then show us you latest code if you’re still
stuck.

We can walk you though directly parsing /etc/group if necessary, but
unless you’re doing something low level or your task is specificly about
such parsing, it is better to use the presuppplied grp module.

Cheers,
Cameron Simpson cs@cskk.id.au

Hi Cameron,

Thank you for your response.

I misunderstood something about what I have to do:

I will recive a text file like:

groupA:1919:user1, user2, user.3, uss.er4
groupB::user1, user2, user.3, uss.er4

Many lines like this. So,I have in the first Field the Group name, second field GID and third field the users separate them by ,

I need read that file and, for each line field 1 check if that group exist (in/etc/group). I believe using cut and | grep or something like that.
Second field, the same, cheque if that GID is already in use,
Third field the same with the users but delimited by ,

I think using read, readlines and for loop.

Then whit all that data create the groups, with some ID (if there no id use the next available) and the users into each group. Maybe using os.system groupadd, groupmod

I will continue writing and I’ll share it with you if I still stuck.

Thank you for help me.

I misunderstood something about what I have to do:

I will recive a text file like:

groupA:1919:user1, user2, user.3, uss.er4
groupB::user1, user2, user.3, uss.er4

Many lines like this. So,I have in the first Field the Group name, second field GID and third field the users separate them by ,

Right. Much like the /etc/group file.

I need read that file and, for each line field 1 check if that group exist (in/etc/group). I believe using cut and | grep or something like that.
Second field, the same, cheque if that GID is already in use,
Third field the same with the users but delimited by ,

This is good. Notice that the /etc/group file and your input data file
have the same format. T👍his means that you can write the same parser
fo each of you want. (Or you can use grp.getgrnam() for the /etc/group
lookup side of things.)

I think using read, readlines and for loop.

Try to avoid readlines() - it sucks everything into memory. It is
usually better to write a loop over the text file:

with open("your-input-file") as f:
    for line in f:
        # line is a single line from the file
        # but it includes the trailing newline, so let's strip it 
        # off
        line = line.rstrip()
        ... parse line into fields etc etc ...

Then whit all that data create the groups, with some ID (if there no id
use the next available) and the users into each group. Maybe using
os.system groupadd, groupmod

Look at the str.split method for your parsing. The group file has colon
separated fields, so splitting on a colon breaks the line into group
name, gid, user list. The you can repeat that on the user list by
splitting on a comma.

Cheers,
Cameron Simpson cs@cskk.id.au

Thank you for your time Cameron. I keep working on it. I’ll ask you If I get stuck again.

Thanks for your help.

Hi, I started over from scratch.

I revived a file with info about groups, gid and users.
I used argparse to pass that file.
Then I open it using with in read mode:

with open(args.variable,‘r’) as variable2:
for variable3 in variable2:
variable3=variable3.srtip()
print(Variable3.strip())

The output I get is the same that I have in the file I passed.
group1::user1.user2,user3
groupb:1961:usera.groupb,groupc

I would like to use awk command to split the Fields that I need to check users and passwords.
I wrote: awk -F’:’ ‘{print $1}’ to get the group of each line.

How can I put that awk command in my loop to get just the first field of each line?

Any idea?

Thank you!

Hi guys,

I made this script:

with open(’/etc/group’,‘r’) as groupslist:
for eachline2 in groupslist:
groupname2 = os.popen('echo ’ + eachline2.strip() + ‘| cut -d":" -f1’).read()

print(groupname2)

with open(args.filename,‘r’) as data:
for eachline in data:
groupname = os.popen('echo ’ + eachline.strip() + ‘| cut -d":" -f1’).read()
gid = os.popen('echo ’ + eachline.strip() + ‘| cut -d":" -f2’).read()
users = os.popen('echo ’ + eachline.strip() + ‘| cut -d":" -f3’).read()
#print('Group Name: ’ + groupname + ’ GID = ’ + gid + ‘Usuarios :’ + users)

I have:
in variable groupname = the groups of the file, line by line.
In variablegid = the GID of each group line by line
In users = the users of each group debilitated by ,

I opened the /etc/group to check if each group already exist in the system or no.

I need some help to make that checking
And to make a new variable that separate by , the contents of users.

Once I do that, I need to create that groups (those that doesn’t exist in the system), with its GI (if none GID is written, use the next available) and with those users that belongs to that group.

If you can give me some ideas how to continue I’ll appreciate it.
THANKYOU

with open(’/etc/group’,‘r’) as groupslist:
for eachline2 in groupslist:
groupname2 = os.popen('echo ’ + eachline2.strip() + ‘| cut -d":" -f1’).read()

print(groupname2)

Is there a reason you’re piping to cut(1) to extract a field? This is an
extremely slow way to do this when:

fields = groupline2.split(':')
groupname2 = fields[0]

is both clearer and much faster?

Using cut and awk is fine for a shell script, that’s part of what
they’re for. But the shell is not a rich language for string processing.
However Python has a whole suite of str methods for cutting strings up
which are very well suited to what you’re doing here.

Also, constructing a shell command such as yours:

echo ... | cat ...

is something to be done with far greater care.

See: xkcd: Exploits of a Mom That example is for SQL, but the shell (and,
generally, any constructed command string) has the same hazards.

with open(args.filename,‘r’) as data:
for eachline in data:
groupname = os.popen('echo ’ + eachline.strip() + ‘| cut -d":" -f1’).read()
gid = os.popen('echo ’ + eachline.strip() + ‘| cut -d":" -f2’).read()
users = os.popen('echo ’ + eachline.strip() + ‘| cut -d":" -f3’).read()
#print('Group Name: ’ + groupname + ’ GID = ’ + gid + ‘Usuarios :’ + users)

I have:
in variable groupname = the groups of the file, line by line.
In variablegid = the GID of each group line by line
In users = the users of each group debilitated by ,

I opened the /etc/group to check if each group already exist in the system or no.

I need some help to make that checking

I would makea function like:

def check_for_group(group_name):

which contained your code to read the group file and look for
group_name, and to return True if found and False otherwise. Then you
can write stuff like:

if check_for_group(group_name):
    ... the group was found ...
else:
    ... the group was not found ...

And to make a new variable that separate by , the contents of users.

See the str.split method in the Python documentation.

Once I do that, I need to create that groups (those that doesn’t exist
in the system), with its GI (if none GID is written, use the next
available) and with those users that belongs to that group.

You could write a more general version of check_for_group() which
scanned the /etc/group file and returned a dict mapping group names to a
tuple of (gid, members). Then you can implement check_for_group() by
looking in that dict, and compute the next GID by computing the maximium
GID in the dict and adding 1.

You can make a new group by either executing the groupadd command via
subprocess, or opening the group file for append and just writing a
valid group definition line. Take a copy of it (by hand) first, in case
you destroy it. Or work on a totally different file which is a copy of
/etc/group.

Do not develop this code as root, you can do all sorts of damage to
your system with accidents.

Cheers,
Cameron Simpson cs@cskk.id.au

Hi Cameron,

Thank you so much to take your time to teach me more about Python.

I going to read what you said.

I was thinking and summarizing, I should need:

  • Open and read the file passed
  • Check groups in /etc/goup
  • If statement: If the group doesn’t exist, use that line to create it with GID and those users in it.
  • Another statement: If the line has GID use it, if not don’t use groupmod.

Or something like that.
I’ll be working on it today.

I’ll show you how it ifs going after.

Thank you again!

I like that, is much clear.