Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Some numpty ran chown -R username. in the /home folder on our webserver thinking he was in the desired folder. Needless to say the server is throwing a lot of wobbelys.

We have over 200 websites and I don't want to chown them all individually so I'm trying to make a script that will change the owner of all the folders to the folder name, without the trailing /.

This is all I have so far, once I can remove the / it will be fine, but I'd also like to check if the file contains a . in it, and if it doesn't then run the command, otherwise go to the next one.

#!/bin/bash
for f in *

do

    test=$f;
    #manipluate the test variable
    chown -R $test $f

done

Any help would be great!

Thanks in advance!

share|improve this question

2 Answers 2

up vote 3 down vote accepted

Assuming that all folders in the /home/ directory represents user names, you can use:

for dir in /home/*/; do
    # strip trailing slash
    homedir="${dir%/}"
    # strip all chars up to and including the last slash
    username="${homedir##*/}"

    case $username in
    *.*) continue ;; # skip name with a dot in it
    esac

    chown -R "$username" "$dir"
done

I suggest to run a test loop before, checking whether the user name actually matches a home directory.

This AWK command retrieves the home directory for a given user.

awk -F: -v user="$username" '{if($1 == user){print $6}}' < /etc/passwd

Checking this result against the existing home dir is an exercise for the reader.

share|improve this answer
    
Great that works! Is there anyway to make it so it skips files with a . in their name there are some hidden .* files and some files that are xxx.xxx and so on. Once it does that I can run it and it should all work! –  Shikoki Oct 20 '12 at 9:47
    
Thanks a lot, saw your updated post and it's done the job! Cheers again –  Shikoki Oct 20 '12 at 9:54
    
@Shikoki To prevent hidden dot-names from showing, you can use shopt -u dotglob before using globbing. It is not strictly necessary here because *.* also matches a single dot though. –  Lekensteyn Oct 20 '12 at 10:10
    
+1 for making proper use of string manipulation. Well done, Sir! –  Alexander Janssen Oct 20 '12 at 10:24

You can use the basename command to provide the last component of a path

for dir in /home/*
do
    if [ -d "$dir" ]
    then
        username=$(basename "$dir")
        chown -R "$username" "$dir"
    fi
done

although I would initially run it as

for dir in /home/*
do
    if [ -d "$dir" ]
    then
        username=$(basename "$dir")
        echo "chown -R $username $dir"
    fi
done

to make sure it was sane.

share|improve this answer
    
Aye I ran the echo first just to make sure it would do what was expected, I used Lekens code as I never saw yours but thank you anyway! –  Shikoki Oct 20 '12 at 9:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.