I wrote the following script to remove users from a wordlist. The wordlist has 3 or 4 fields which are First Name, Middle Name, Last Name, and User ID. I am using awk to create a username that comprises of the user's firstname initial, lastname and last two digits of their ID. Then using the command userdel with flag r to remove users with their home directories as well.
However when I run the script it gives me an error saying the following:
Usage: userdel [options] LOGIN
Options:
-f, --force force some actions that would fail otherwise
e.g. removal of user still logged in
or files, even if not owned by the user
-h, --help display this help message and exit
-r, --remove remove home directory and mail spool
-R, --root CHROOT_DIR directory to chroot into
-Z, --selinux-user remove any SELinux user mapping for the user
The script:
#! /bin/bash
# Removing users using positional parameters
getusername(){
line=${1}
len=`echo ${line}|awk '{ FS = " " } ; { print NF}'`
if [[ ${len} -eq 3 ]]
then
initial=`echo ${line}| awk {'print $1'} |cut -c1`
lastname=`echo ${line} | awk {'print $2'}`
id=`echo ${line}| awk {'print $3'}|grep -o '..$'`
username=`echo ${initial}${lastname}${id} |tr '[:upper:]' '[:lower:]'`
elif [[ ${len} -eq 4 ]]
then
initial=`echo ${line} | awk {'print $1'} |cut -c1`
lastname=`echo ${line} | awk {'print $3'}`
id=`echo ${line}| awk {'print $4'}|grep -o '..$'`
username=`echo ${initial}${lastname}${id} |tr '[:upper:]' '[:lower:]'`
else
echo "Line ${line} is not expected as it should be considered for creating Username and Password"
fi
}
sudo userdel -r $getusername
How to invoke userdel?
userdel -r username
This deletes the account of user username, and removes that user's home directory and associated mail files.
For that, you need to use a variable instead of to invoke a function.
Otherwise userdel will complain, like it is already doing or like just typing userdel.
Related
Looking for a simpler way to validate a user is requesting a password change for an account that is local and its a valid user ID format.
Valid user ID format is - ^[^a-zA-Z]*[a-zA-Z][^a-zA-Z]*t.*
With the first character being upper or lowercase letter followed by the letter t followed by 4 alphanumeric characters for a total of 6 characters long.
Currently I am using the follow to evaluate an if else - grep -Eow '\w{6}' /etc/passwd | grep ^[^a-zA-Z]*[a-zA-Z][^a-zA-Z]*t.* /etc/passwd
if grep -Eow '\w{6}' /etc/passwd | grep ^[^a-zA-Z]*[a-zA-Z][^a-zA-Z]*t.* /etc/passwd | grep -c "$cUname" $1 >/dev/null 2>&1; then
echo -e "$linuxPassword\n$newPassword\n$newPassword" | passwd
else
echo "Account is not a local account on this machine or not a valid account"
fi
Is there a better way of doing this?
if [[ $cUname == [[:alpha:]]t[[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]] ]] &&
grep -q "^${cUname}:" /etc/passwd
then
echo "OK to change password"
else
echo "$cUname: invalid username or username not found"
fi
I am trying to create a script which will list the name of the user, only if that specific user has a specific and available directory in his folder.
#!/bin/bash
for i in `cat /etc/passwd | cut -d : -f5\,6 | cut -d : -f2`
do
cd $i
if [ -d public_html ]
then
echo `cat /etc/passwd | cut -d : -f5,6 | cut -d : -f1`
fi
done
First, I get a list of all the user names that have home folders.
Then, for each user, I enter in his directory
If in his directory, public_html directory is found, echo the user.
When I run this in the terminal, all the users are listed:
cat /etc/passwd | cut -d : -f5,6 | cut -d : -f1
However, I need to somehow get the user i from that whole list.
Can anybody be so kind to explain what I´m doing wrong, and what to look out for?
You're getting the wrong result because you're checking for a file (with -f). Try using -d.
Using cat and cut is not bash either and can easily be replaced with script in most cases.
I'd do something like this:
while IFS=: read -r user pass uid gid desc homedir shell; do [ -d "$homedir"/public_html ] && echo "$user"; done < /etc/passwd
We set the field separator (IFS) to : (since that's what /etc/passwd uses), we read the file in and set the variables we want to use.
Then for each line we do the test and (&&) if the test is successful we echo the result.
The quotes are not really necessary since we know the formatting of the file but good practice.
If users' home directories are set up in the standard way:
cd /home
for pubdir in */public_html/ ; do
echo "${pubdir%%/*}"
done
I did it ghetto style...
#!/bin/bash
counter=0
for i in `cat /etc/passwd | cut -d : -f6`
do
if [ -r $i ]
then
cd $i
if [ -d public_html ]
then
counter2=2
for j in `cat /etc/passwd | cut -d : -f5`
do
counter2=$(($counter2 + 1))
if [ $counter -eq $counter2 ]
then
echo $j
fi
done
fi
counter=$(($counter + 1))
fi
done
#!/bin/bash
getent passwd | awk -F: '{printf "%s\t%s\n",$1, $6}'| while read -r user home
do
if [ -d ${home}/public_html ] ; then
echo ${user}
fi
done
This should work irrespective of use of /etc/passwd or ldap ...
I have created a script which lists list of users from the server and emails them.
I can get the user list from multiple host, and also it filters a file called ignore.txt (which has unwanted users) before sending the list.
The challenge is now, that /etc/passwd has users whose account are locked (not active). Is it possible to edit the script below and send a list of users who are active, and aslo a list of users whose account is locked?
The new report should reflect a list of active users and also a list of disabled/locked users.
My current script is the following:
#!/bin/ksh
#title :user.list.script.ksh
#description :This script collects list of users from the server
#note :Multiple hosts can be added
#HOSTS format:
HOSTS="00.00.00.00-DEV" #example "hostname-DEV"
FILE=/home/zaira/report.txt #list will be saved in report.txt
date > $FILE
echo >> $FILE
for host in $HOSTS; do
ip=$(echo $host|cut -d '-' -f 1)
title=$(echo $host|cut -d '-' -f 2)
ssh $ip -q -l zaira cat /etc/passwd | awk -F: '{printf("%-30s\t%-30s\t%-40s\n ", $1, $3, $5)}' >/tmp/temp 2>/dev/null
echo "$title instance" >> $FILE
perl -e 'print "=" x 65,"\n"' >>$FILE
#we filter through ignore.list to remove unwanted users
cat /tmp/temp|grep -wvf /home/zaira/ignore.list|sort >> $FILE
echo >> $FILE
done
rm -f /tmp/temp
mailx -r From-DEV-no-reply#abc.com -s " User list" zairabanu#abc.com < "$FILE"
Going from memory, as it's been a loo,ooo,ooo,ong time since I've used AIX, you can use lsuser to get locked accounts:
lsuser -a account_locked ALL | grep '=true$' | awk '{ print $1 }'
If you don't want to manually maintain an ignore list, you can get a list of those users who can log in:
lsuser -a login ALL | grep '=true$' | awk '{ print $1 }'
With respect to the OP original script, you can probably now do something like:
lsuser -a login ALL | grep '=true$' | awk '{ print $1 }' > /tmp/temp
Actually modifying the original script is left up to the OP.
This script looks for all users that have the string RECHERCHE inside them. I tried running it in sudo and it worked, but then stopped at line 8 (permission denied). Even when removing the sudo from the script, this issue still happens.
#!/bin/bash
#challenge : user search and permission rewriting
echo -n "Enter string to search : "
read RECHERCHE
echo $(cat /etc/passwd | grep "/home" | cut -d: -f5 | grep -i "$RECHERCHE" | sed s/,//g)
echo "Changing permissions"
export RECHERCHE
sudo ./challenge2 $(/etc/passwd) &
The second script then changes permissions of each file belonging to each user that RECHERCHE found, in the background. If you could help me figure out what this isn't doing right, it would be of great service. I
#!/bin/bash
while read line
do
if [-z "$(grep "/home" | cut -d: -f5 | grep -i "$RECHERCHE")" ]
then
user=$(cut -f: -f1)
file=$(find / -user $(user))
if [$(stat -c %a file) >= 700]
then
chmod 700 file 2>> /home/$(user)/challenge.log
fi
if [$(stat -c %a file) < 600]
then
chmod 600 file 2>> /home/$(user)/challenge.log
fi
umask 177 2>> /home/$(user)/challenge.log
fi
done
I have to idea what I'm doing.
the $(...) syntax means command substitution, that is: it will be replaced by the output of the command within the paranthesis.
since /etc/passwd is no command but just a text-file, you cannot execute it.
so if you want to pass the contents of /etc/passwd to your script, you would just call it:
./challenge2 < /etc/passwd
or, if you need special permissions to read the file, something like
sudo cat /etc/passwd | ./challenge2
also in your challenge2 script, you are using $(user) which is wrong as you really only want to expand the user variable: use curly braces for this, like ${user}
/etc/passwd?
not what you were asking, but you probably should not read /etc/passwd directly anyhow.
if you want to get a list of users, use the following command:
$ getent passwd
this will probably give you more users than those stored in /etc/passwd, as your system might use other PAM backends (ldap,...)
I have started writing a small piece of code to print all the list of users available in the linux box. But I want to pass one by one user into my command to display each user details together.
to list all users
root#bt# getent passwd | grep /home/ | cut -d ':' -f 1
root
san
postgres
Now I want to pass one by user in to the below command to display each user details together.
root#bt# chage -l ${user1} ; chage -l ${user2} etcc.
should I need to user for loop or while loop here?
can any one help me in suggesting how to write the same?
You can use the while loop:
getent passwd | grep /home/ | cut -d ':' -f 1 | \
while read user ; do
chage -l "$user"
done
or the for loop:
for user in $(getent passwd | grep /home/ | cut -d ':' -f 1) ; do
chage -l "$user"
done
or xargs:
getent passwd | grep /home/ | cut -d ':' -f 1 | \
xargs -n1 chage -l
I would use xargs, which runs a command on each output item of the previous pipe:
getent passwd | grep /home/ | cut -d ':' -f 1 | sudo xargs -I % sh -c '{ echo "User: %"; chage -l %; echo;}'
sudo is used to get information about all users, if you don't have access to this information then you can remove sudo
-I % is used to specify that % is a placeholder for the input item (in your case a user)
sh -c '{ command1; command2; ...;}' is the command executed by xargs on every % item; in turn, the command sh -c allows multiple shell commands to be executed
'{ echo "User: %"; chage -l %; echo;}' echoes the current user in %, then runs chage -l on this user and finished with a final empty echo to format the ouput