Shell script that lists files with different owner than the folder

Hello, I'm trying to write a script which is listing files based on different preferences, like filetype or permissions. All is fine, except for one: I want to list files in /home which has a different owner than the home directory it is in.

Here is an example:
/home/UserA is the directory, and /home/UserA/foobar.txt is the file, that is owned by UserB.
If I would have to use a fixed user, this wouldn't be a problem, as I could just do

find /home/UserA \! -user UserA -exec echo "{}" is not owned by UserA \;

But I don't know, how can I use variables, that modifies the output and the checking based on who's home directory (for a /home/UserB/foobar.txt owned by UserA scenario) it is in. I was thinking about using awk to get the owner of the home directory and the file and compare it, but it doesn't feel right.
Basically I just have to find a way, to cycle through the home directories and replace the 3 UserA in my script, like this:

/home/UserA
/home/UserB
/home/UserC

find /home/UserA \! -user UserA -exec echo "{}" is not owned by UserA \;
find /home/UserB \! -user UserB -exec echo "{}" is not owned by UserB \;
find /home/UserC \! -user UserC -exec echo "{}" is not owned by UserC \;

I would appreciate any idea.

Something like this?

#!/bin/bash

DIR="/home/UserA /home/UserB /home/UserC"
for dir in $DIR
do
  user=$( basename $dir )
  find $dir ! -user $user -exec echo "{}" is not owned by $user \;
done

--ahamed

1 Like

Yes, like this, but my main problem is processing the folderlist in /home, because the script should work in any enviroment, not just with predefined names.

This:

cd /home
ls -l | awk '{print $3}'

would get a owners list for me, or with

cd /home
ls -l | awk '{print $8}'

I could get a list of folders (and files, but this is irrelevant in this case), but as I mentioned my problem is how to precess and use that list.

Sorry, that I left this out of my original post. I also forgot to mention, that the search has to go through every file, no matter, how deep it is in the folder tree. This is why I used 'find'.

And before I forget, thank you for the help! :slight_smile:

More generic would be to get all the users in the system and then search the home directories right?

--ahamed

---------- Post updated at 02:11 PM ---------- Previous update was at 01:51 PM ----------

Following script takes the users from /etc/passwd and searches their home directory for any files which they don't own. You definitely don't want to search any system accounts. So you can update the excp_list with the users you want to skip separated by pipe.

#!/bin/bash

excp_list="(root|daemon)"
awk -F: '{print $1,$6}' /etc/passwd | while read user home_dir
do
  test $(echo $user | egrep -c "$excp_list") -ge 1 && continue
  test -z "$home_dir" && continue
  find $home_dir ! -user $user -exec echo "{}" is not owned by $user \;
done  

HTH
--ahamed

1 Like

Well, I was thinking about getting a userlist with

cat /etc/passwd | grep /home | cut -d: -f1

but this is messy too (extra results), and does not solve my problem. By generic I meant, that the folders in /home are not called UserA, UserB, etc. which I used in the code here.

cd /home ls -l | awk '{print $8}'

works pretty well, I just have to find a way to insert the result into

DIR="/home/UserA /home/UserB /home/UserC"

this line, instead of UserA,...,etc.

-----------------------------EDIT-------------------------------------------

I liked your first script better as it was less complicated for me. :slight_smile:
Using the folderlist and owners from /home is perfectly fine (I don't have to think about shares and users without home, as the focus is on those who have a home directory) and I just have to list the files that are not owned by the owner of the home directory.
I just have to find a way, to make that list usable.

Try this...

DIR=$( ls -d /home/* )

--ahamed

1 Like

WOW, thank you, that worked just perfectly!

I knew, it can be done very easily, I was just too amateur to find :slight_smile: it.

@ahamed101:

A thank you is on it's way, but I think I got logged out from the site before I posted it, and now a moderator has to approve it. :slight_smile:

Your last code worked, just as it should be, thank you for the easy solution! :b:

I tried however with the code I posted earlier, and it seems, that that one works too. It uses the actual username, not to foldername, so I think it's prettier. I also added a

-type f

option to 'find', because the previous solution included folders too.

So, here is the finished code, what do you think about it? Any mistakes, that I should have seen?

#!/bin/bash

cd /home
DIR=$( ls -l | awk '{print $3}' )

for dir in $DIR
do
  user=$( basename $dir )
  find $dir ! -user $user -type f -exec echo "{}" is not owned by $user \;
done

And again: thank you for the help! :slight_smile:

DIR=$( ls -l | awk '{print $3}' ) this will give you the user's right?... Shouldn't it be DIR=$( ls -d /home/* ) ?

--ahamed

DIR=$( ls -l | awk '{print $3}' )

will return the name of the owner for every item in the folder, while your solution returns the list of folders. They are pretty much the same, but if we want to check owners, I think mine is safer.

In that case, which directories will you search?

My solution gets the directory list and then extracts the user and does a find (provided all the user home directory has the the username in it). I think what you want is the the script which you mentioned as complicated, that does the job you want!

--ahamed