0

I'm writing a script that will take the list of users from a folder and compare them against the list of folders in /home/ and output any folders that don't match the list of active users on the server. Right now, I pretty much have it where I want it, but I'm stumped on how to take the list of things I want to filter out in an array, compare that to the output of $COMPARE and then only output the folders that don't match what I'm trying to filter out.

Here's my code thus far:

# Script for finding and displaying home folders that don't currently belong to an active user on the server
HOMEOUT=$(mktemp)
USEROUT=$(mktemp)
USERS=( $(find /var/cpanel/users/ -maxdepth 1 -type f -printf '%P\n' | sort >$USEROUT) )
HOME=( $(find /home* -maxdepth 1 -type d -printf '%P\n' | grep -v '^$' | sort >$HOMEOUT) )
FILTER=( 'mysql' 'migrate-sslrigs' 'rvadmin' 'cpeasyapache' 'lost+found' 'cpanelbranding' 'installd'
    'cprestore' 'cprubybuild' 'cprubygemsbuild' 'MySQL-install' 'mysql_upgrade' 'securervsite' 'virtfs' 'zabbix' )


# Compare the two files and only output folders from /home/ which don't match the active_users list
COMPARE=`comm -23 $HOMEOUT $USEROUT`

I was thinking that "case" might be the way to go here, but I'm having issues figuring it out and I'm not certain if that's even the best way to handle this. Any guidance/assistance would be greatly appreciated.

UPDATED

Here's the current code:

HOMEOUT=$(mktemp)
USEROUT=$(mktemp)
USERS=( $(find /var/cpanel/users/ -maxdepth 1 -type f -printf '%P\n' | sort >$USEROUT) )
HOME=( $(find /home* -maxdepth 1 -type d -printf '%P\n' | grep -v '^$' | sort >$HOMEOUT) )
FILTER=( 'mysql' 'migrate-sslrigs' 'rvadmin' 'cpeasyapache' 'lost+found' 'cpanelbranding' 'installd'
        'cprestore' 'cprubybuild' 'cprubygemsbuild' 'MySQL-install' 'mysql_upgrade' 'securervsite' 'virtfs' 'zabbix' 'cpeasyapache'
        '.cpan' '.cpcpan' '.cpanm' )


# Compare the two files and only output folders from /home/ which don't match the active_users list
COMPARE=`comm -23 "$HOMEOUT" "$USEROUT" |
            comm -23 - <(
                for f in "${FILTER[@]}"; do
                    echo "$f"
                done)`

# Find the disk space of each folder
 pushd /home/ >/dev/null
for x in "$COMPARE"; do
        du -s $x | sort -n | cut -f 2-|xargs -i du -sh {}
done
  popd >/dev/null


# House cleaning
rm -f $HOMEOUT $USEROUT

When I run the script with bash -x it displays the following:

+ FILTER=('mysql' 'migrate-sslrigs' 'rvadmin' 'cpeasyapache' 'lost+found' 'cpanelbranding' 'installd' 'cprestore' 'cprubybuild' 'cprubygemsbuild' 'MySQL-install' 'mysql_upgrade' 'securervsite' 'virtfs' 'zabbix' 'cpeasyapache' '.cpan' '.cpcpan' '.cpanm')
++ comm -23 /tmp/tmp.fxYQB27380 /tmp/tmp.vwLWZ27381
++ comm -23 - /dev/fd/63
+++ for f in '"${FILTER[@]}"'
+++ echo mysql
+++ for f in '"${FILTER[@]}"'
+++ echo migrate-sslrigs
+++ for f in '"${FILTER[@]}"'
+++ echo rvadmin
+++ for f in '"${FILTER[@]}"'
+++ echo cpeasyapache
+++ for f in '"${FILTER[@]}"'
+++ echo lost+found
+++ for f in '"${FILTER[@]}"'
+++ echo cpanelbranding
+++ for f in '"${FILTER[@]}"'
+++ echo installd
+++ for f in '"${FILTER[@]}"'
+++ echo cprestore
+++ for f in '"${FILTER[@]}"'
+++ echo cprubybuild
+++ for f in '"${FILTER[@]}"'
+++ echo cprubygemsbuild
+++ for f in '"${FILTER[@]}"'
+++ echo MySQL-install
+++ for f in '"${FILTER[@]}"'
+++ echo mysql_upgrade
+++ for f in '"${FILTER[@]}"'
+++ echo securervsite
+++ for f in '"${FILTER[@]}"'
+++ echo virtfs
+++ for f in '"${FILTER[@]}"'
+++ echo zabbix
+++ for f in '"${FILTER[@]}"'
+++ echo cpeasyapache
+++ for f in '"${FILTER[@]}"'
+++ echo .cpan
+++ for f in '"${FILTER[@]}"'
+++ echo .cpcpan
+++ for f in '"${FILTER[@]}"'
+++ echo .cpanm

However, the output still displays any of said folders that were supposed to be filtered out. I feel like the echo in itself isn't enough and there's probably something missing to actually remove anything that matches $FILTER from the output.

Thoughts?

1 Answer 1

2

You can replace your last line with this:

COMPARE=`comm -23 "$HOMEOUT" "$USEROUT" |
            comm -23 - <(
                for f in "${FILTER[@]}"; do
                    echo "$f"
                done | sort)`

This part:

<(for f in "${FILTER[@]}"; do
    echo "$f"
  done | sort)

is substituted by bash with the file name of the reading end of a pipe connected to the output of the script within <( ), the latter printing sorted members of FILTER array one per line.

This command:

comm -23 - <(
    for f in "${FILTER[@]}"; do
        echo "$f"
    done | sort)`

outputs lines from its input which don't appear in the FILTER array.

Sign up to request clarification or add additional context in comments.

5 Comments

That worked great, thanks. I knew I was making it harder than it should be, but just couldn't piece it all together.
You're welcome:) Although I forgot to sort the array. Will fix the answer. There are many ways to make this even simpler still.
I did some additional testing on this and it's not working exactly as expected, so it seems I jumped the gun. It lists the excluded names with the echo, but the output still displays them. I'll update the initial post with what's happening.
This is most likely because the array wasn't sorted as I noted in my previous comment. comm operates on sorted input. Fixed the answer now.
Aha, that did do the trick. I read about the lack of sorting, but for some reason it didn't click in my mind that it wasn't already sorted after you mentioned that. All set now. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.