Script to run chown on all folders and setting the owner as the folder name minus the trailing /

10,099

Solution 1

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.

Solution 2

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:
10,099

Related videos on Youtube

Shikoki
Author by

Shikoki

Updated on September 18, 2022

Comments

  • Shikoki
    Shikoki over 1 year

    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!

  • Shikoki
    Shikoki over 11 years
    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
    Shikoki over 11 years
    Thanks a lot, saw your updated post and it's done the job! Cheers again
  • Shikoki
    Shikoki over 11 years
    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!
  • Lekensteyn
    Lekensteyn over 11 years
    @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.
  • Alexander Janssen
    Alexander Janssen over 11 years
    +1 for making proper use of string manipulation. Well done, Sir!
  • Skeer
    Skeer about 7 years
    @Lekensteyn Thank you so much for this script! I ran into an issue where I needed EXACTLY what you posted. You saved me a ton of time. AAA++++