Vladyslav Tkachuk
Vladyslav Tkachuk

Reputation: 11

my script deletes user accounts that have not been logged in for more than 30 days, in fact it works, but it deletes some system accounts

It works, but also deletes some system accounts...i don't know why

#!/bin/bash

# This script takes everyone with id>1000 from /etc/passwd and removes every user account in case if it hasn't been used for the last 30 days.

# Make sure that script is being executed with root priviligies.

if [[ "${UID}" -ne 0 ]]
then
echo "You should run this script as a root!"
exit 1
fi

# First of all we need to know id limit (min & max)

USER_MIN=$(grep "^UID_MIN" /etc/login.defs)

USER_MAX=$(grep "^UID_MAX" /etc/login.defs)

# Print all users accounts with id>=1000 and <=6000 (default).

awk -F':' -v "min=${USER_MIN##UID_MIN}" -v "max=${USER_MAX##UID_MAX}" ' { if ( $3 >= min && $3 <= max ) print $0}' /etc/passwd

# This function deletes users which hasn't log in in the last 30 days

# Make a color output message

for accounts in ` lastlog -b 30 | sed "1d" | awk ' { print $1 } '`

do

userdel $accounts 2>/dev/null

done

echo -e "\e[36mYou have successfully deleted all user's account which nobody logged in in the past 30 days.\e[0,"

exit 0

Upvotes: 1

Views: 785

Answers (2)

Cyrus
Cyrus

Reputation: 88646

With bash and GNU grep:

#!/bin/bash

# I left out the check for root user

# get only the numbers from each line
# \K removes the matching part before \K (from left to right)
USER_MIN=$(grep -Po "^UID_MIN *\K.*" /etc/login.defs)
USER_MAX=$(grep -Po "^UID_MAX *\K.*" /etc/login.defs)

# create an associative array, see: help declare
declare -A users
# read all users with its uid to this associative array
while IFS=":" read -r user x uid x; do users[$user]="$uid"; done </etc/passwd
# see output of: declare -p users

# remove all unwanted lines including headline. NR is line number
lastlog -b 30 | awk '! /Never logged in/ && NR>1 {print $1}' |
  while read -r user; do

    # -ge: greater-than-or-equal
    # -le: less-than-or-equal
    if [[ ${users[$user]} -ge $USER_MIN ]] && [[ ${users[$user]} -le $USER_MAX ]]; then
      echo "delete user $user with uid ${users[$user]}"
      # add your code here to delete user $user
    fi
  done

Upvotes: 1

KamilCuk
KamilCuk

Reputation: 141030

You do not apply the awk -F':' -v "min=${USER_MIN##UID_MIN}" -v "max=${USER_MAX##UID_MAX}" ' { if ( $3 >= min && $3 <= max ) print $0}' /etc/passwd filter to lastlog output....

Join the list from lastlog with the list of users from /etc/passwd and filter UID with proper number range.

lastlog -b30 | sed 1d | awk '{print $1}' |
sort | join -t: -11 -21 -o2.1,2.3 - <(sort /etc/passwd) |
awk -F: -v "min=${USER_MIN##UID_MIN}" -v "max=${USER_MAX##UID_MAX}" '$2 >= min && $2 <= max {print $1}' |
xargs -n1 echo userdel

Notes:

Upvotes: 2

Related Questions