2

I am able to get both listings ( /etc/passwd and /home ) but how to script something like read line of /etc/passwd, parse home directory, then look for that in /home . If it doesn't exist, throw an error, if it does exist, move along.

/etc/passwd home dir listing for users

cut -d":" -f6 /etc/passwd | grep home | sort

user listing from /home

ls -1 /home | (while read line; do echo "/home/"$line; done)

Maybe right out output from first command to a file, then read each line into a find command and...or, test with

if [ -d "$DIRECTORY" ]; then
echo "directory found for user that doesn't exist"
fi

Now how to put it all together...

EDIT: isedev had exactly what I needed. I may have mis-worded my original message...we have been cleaning up users, but not cleaning up their /home directory. So I want to know what /home directories still exist that don't have /etc/passwd entries.

this is what worked to a T

for name in /home/*; do if [ -d "$name" ]; then cut -d':' -f6 /etc/passwd | egrep -q "^$name$" if [ $? -ne 0 ]; then echo "directory $name does not correspond to a valid user" fi fi done

from now on, we will be running

userdel -r login

mohuddle
  • 23
  • 6
  • Not totally reliable. accounts GENERALLY have their homedir in /home, but not all of them. e.g. consider the root account, which usually lives off in `/root` – Marc B Oct 07 '14 at 19:39
  • @MarcB Unless the OP wants to know if there are directories under /home which do not correspond to entries in /etc/passwd. – isedev Oct 07 '14 at 19:43
  • Are you worried about directories in `/home` claimed by more than one entry in `/etc/passwd`? – Jonathan Leffler Oct 07 '14 at 19:56

3 Answers3

2

as 1st approximation:

perl -F: -lane 'next if m/^#/;print "$F[5] for user $F[0] missing\n" unless(-d $F[5])' /etc/passwd

if you want find the differences between the /etc/passwd and the /home

comm <(find /home -type d -maxdepth 1 -mindepth 1 -print|sort) <(grep -v '^#' /etc/passwd  | cut -d: -f6| grep '/home' | sort)

in an narrow form

comm    <(
            find /home -type d -maxdepth 1 -mindepth 1 -print |sort
        ) <(
            grep -v '^#' /etc/passwd  |cut -d: -f6 |grep /home |sort
        )

if you will use

  • comm ... (without args as above) will show 3 colums 1.) only in /home 2.)only in /etc/passwd 3.) common
  • comm -23 .... - will show directories what are only in the /home (and not in the /etc/passwd)
  • comm -13 .... - will show dirs what are only in the /etc/passwd and not in the /home
  • comm -12 .... - will show correct directories (exists in the /etc/passwd and the /home too)

I'm not sure with the -{max|min}depth on the AIX..

clt60
  • 62,119
  • 17
  • 107
  • 194
2

This will report all home directories from /etc/passwd that should be in /home but aren't:

cut -d":" -f6 /etc/passwd | grep home | sort | 
    while read dir; do [ -e "$dir" ] || echo Missing $dir; done

And this one reports all that don't exist:

cut -d":" -f6 /etc/passwd | while read dir; do 
    [ -e "$dir" ] || echo Missing $dir
done
terdon
  • 3,260
  • 5
  • 33
  • 57
1

So, assuming you want to know if there are directories under /home which do not correspond to existing users:

for name in /home/*; do
    if [ -d "$name" ]; then
        cut -d':' -f6 /etc/passwd | egrep -q "^$name$"
        if [ $? -ne 0 ]; then
            echo "directory $name does not correspond to a valid user"
        fi
    fi
done

Then again, this assumes you are not using a name service such as LDAP or NIS, in which case, change the line starting with cut to:

getent passwd | cut -d':' -f6 | egrep -q "^$name$"
isedev
  • 18,848
  • 3
  • 60
  • 59
  • +1. As a side note, you could also simplify to `for name in /home/*; do [ -d "$name" ] && cut -d':' -f6 /etc/passwd | grep q "^$name$" || echo "directory $name does not correspond to a valid user"; done`. I would also use simple `grep`, there's no need for `egrep` here and, anyway, that's been deprecated (at least for GNU `grep`) in favor of `grep -E` for some years now. – terdon Oct 07 '14 at 20:03
  • @terdon all good points (well, except the 'deprecated' part - makes me feel old). – isedev Oct 07 '14 at 20:05
  • Tell me about it :). I've gotten into the habit of using `grep -E` though since the man page suggests it. – terdon Oct 07 '14 at 20:06
  • POSIX 2008 standardizes [`grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html) and the `-E` option; there is no longer a separate `egrep` (or `fgrep`). – Jonathan Leffler Oct 07 '14 at 20:13
  • @JonathanLeffler they're still there on many (all?) Linux systems for backwards compatibility. – terdon Oct 07 '14 at 20:18
  • And `gets()` is still in the C library for backwards compatibility too...things get removed from standards long before they're removed from machines. – Jonathan Leffler Oct 07 '14 at 20:30
  • running 1000 times `cut` and `egrep` isn't the best solution for the long passwd files. – novacik Oct 07 '14 at 21:16