Saturday, January 29, 2011

Bash script to create mass series of directories

I need to create a Bash script to go into every user's home folder, seek out a wp-content folder, create a directory uploads under it, and then chmod 0756 uploads.

How do I achieve this?

I imagine I need to use find with a regexp/regex, and then tell it to run another bash script on the results.

  • Something like this should work (I haven't tested it)

    dirs=`find /home -type d -name "wp-content"` 
    
    for dir in $dirs; do
        if [ ! -e $dir/uploads ]; then 
            mkdir $dir/uploads
            chmod 0765 $dir/uploads
        fi
    done
    
    Dennis Williamson : That fails if there's a regular file named "uploads".
    ServerChecker : A space is required after the first bracket and before the next. Doublequotes are probably best around $dir/uploads. I only know this because I tested, got errors, and googled.
    ServerChecker : If we use dirs=$(locate -r 'wp-content$' | grep -i '/home'), it's probably going to run faster than find, I found out. The only catch is that one needs to ensure that updatedb has been run in the past 24 hours.
    Dennis Williamson : @Volomike: `locate` requires the filenames to be in a database that's updated by `updatedb` which is typically run once a day by `cron`. Files and directories that have been created since the last run will be missed by your script if you use `locate`.
    Dennis Williamson : Another problem here is that `find` is recursive and will find directories named "wp-content" below the level you intend. You should use the `-maxdepth` option.
    ServerChecker : In our case, locate is best because it reduces server load and because these wp-content dirs will have been created 4 days ago.
    theotherreceive : @Dennis Yes, you're right on the file called uploads, -e would have been better there. However, there's nothing specified in the question as to the max depth wp-content can reside in
    Dan Andreatta : Instead of using `find`, you can also try `for dir in /home/*/wp-content` ... or similar
  • The above answer is a better one, but here is a primitive, but functional, alternative:

    for i in user1 user2;do mkdir $i/wp-content;chmod 0765 $i/wp-content;done
    

    This assumes you are in the parent directory of all your users, and they are in the same directory.

    This will also fail if there is a file named "uploads", but will continue on.

    Good luck,

    --jed

    Dennis Williamson : You forgot to include the "uploads" directory in your command. You should use `&&` instead of `;` between the `mkdir` and the `chmod`. And what if there are hundreds (or more) users?
    Jed Daniels : All excellent points, although I might not use `&&` because if the directory already exists, I still might want to `chmod` it (not sure, the poster wasn't specific). If there are hundreds of users, I'd probably use the answer from the previous poster, which I mentioned is a better answer. But if there were just a few users, and I wanted to quickly get this out of the way without bothering to create a script, make it executable, then run it, I'd use my admittedly primitive one-liner. Thanks, --jed

0 comments:

Post a Comment