Linux – How to create folders according to date in Linux

bashcroncrontablinux

Is there any other short/easier and smarter way to do the following in Linux?

cd /home/abcd/dammi
mkdir $(date +%Y-%m)
cd $(date +%Y-%m)
mkdir $(date +%d)
# RESULT : /home/abcd/dammi/2011-05/26
cd /home/wxyz/harrami
mkdir $(date +%Y-%m)
cd $(date +%Y-%m)
mkdir $(date +%d)
cd /home/abcd/harrami
mkdir $(date +%Y-%m)
cd $(date +%Y-%m)
mkdir $(date +%d)
cd /home/wxyz/harrami
mkdir $(date +%Y-%m)
cd $(date +%Y-%m)
mkdir $(date +%d)

I need to use crontab to create folders every day and every month inside /home/abcd/dammi, /home/abcd/harrami, /home/wxyz/dammi and /home/wxyz/harrami. Can anyone help me with this?

Info:

    GROUPS : USERS
--------------------
    abcd  : abcd
    wxyz  : dammi, harrami

Best Answer

What about the following:

#!/bin/bash
HOME_DIRS="/home/abcd/dammi /home/wxyz/harrami /home/abcd/harrami /home/wxyz/harrami"
DATE_DIR=$(date +%Y-%m)
DAY_DIR=$(date +%d)

for FOLDER in $HOME_DIRS; do
    mkdir -p "${FOLDER}/${DATE_DIR}/${DAY_DIR}"
done

Well, of course you could also do it without DATE_DIR and DAY_DIR variables but this algorithm makes sure the date is not generated many times which is faster and assures the date to be the same for all users (even if you start it right before midnight and the last directory is created after midnight).

You might also have to think about enhancing the script using chown in order to allow users to write to the newly created directories.

Edit: If you want to create the same folder structure within two /home sub-folders you might combine the script of RolKau with my one:

#!/bin/bash
USER_LIST="dammi harrami"
HOME_SUBDIRS="abcd wxyz"
DATE_DIR=$(date +%Y-%m)
DAY_DIR=$(date +%d)

for HOME_SUBDIR in $HOME_SUBDIRS; do
    for U in $USER_LIST; do
        mkdir -p "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}/${DAY_DIR}"
    done
done

Edit2: I assume the user list contains the user names. So let's extend the script so the directory owner is changed properly as well:

#!/bin/bash
USER_LIST="dammi harrami"
HOME_SUBDIRS="abcd wxyz"
DATE_DIR=$(date +%Y-%m)
DAY_DIR=$(date +%d)

for HOME_SUBDIR in $HOME_SUBDIRS; do
    for U in $USER_LIST; do
        mkdir -p "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}/${DAY_DIR}"
        chown -R "${U}" "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}"
    done
done

Edit3: To change the ownership I think the easiest way is to read the ownership from the directory at /home/<subdir>/<user>

#!/bin/bash
USER_LIST="dammi harrami"
HOME_SUBDIRS="abcd wxyz"
DATE_DIR=$(date +%Y-%m)
DAY_DIR=$(date +%d)

for HOME_SUBDIR in $HOME_SUBDIRS; do
    for U in $USER_LIST; do
        mkdir -p "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}/${DAY_DIR}"
        GROUP_MEMBER=$(stat -c %G "/home/${HOME_SUBDIR}/${U}")
        chown -R "${U}":"${GROUP_MEMBER}" "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}"
    done
done

Sure you could use stat as well to read the owner; but it's slightly slower than just reading it from the variable - as you asked for it:

#!/bin/bash
USER_LIST="dammi harrami"
HOME_SUBDIRS="abcd wxyz"
DATE_DIR=$(date +%Y-%m)
DAY_DIR=$(date +%d)

for HOME_SUBDIR in $HOME_SUBDIRS; do
    for U in $USER_LIST; do
        mkdir -p "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}/${DAY_DIR}"
        OWNER=$(stat -c %U "/home/${HOME_SUBDIR}/${U}")
        GROUP_MEMBER=$(stat -c %G "/home/${HOME_SUBDIR}/${U}")
        chown -R "${OWNER}":"${GROUP_MEMBER}" "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}"
    done
done

Edit4: Alternative solution using hard-coded group membership.

#!/bin/bash
USER_LIST="dammi:group1 harrami:group2"
HOME_SUBDIRS="abcd wxyz"
DATE_DIR=$(date +%Y-%m)
DAY_DIR=$(date +%d)

for HOME_SUBDIR in $HOME_SUBDIRS; do
    for UG in $USER_LIST; do
        G=${UG##*:}
        U=${UG%%:*}
        mkdir -p "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}/${DAY_DIR}"
        GROUP_MEMBER=$(stat -c %G "/home/${HOME_SUBDIR}/${U}")
        chown -R "${U}":"${G}" "/home/${HOME_SUBDIR}/${U}/${DATE_DIR}"
    done
done

Edit5: Looking at your initial post the desired structure might be slightly different. I guess you want to have a sub-directory in /home for each group and only add user-directories for each group member. So here you go:

#!/bin/bash
USER_LIST="dammi:abcd dammi:wxyz harrami:wxyz"
DATE_DIR=$(date +%Y-%m)
DAY_DIR=$(date +%d)

for UG in $USER_LIST; do
    G=${UG##*:}
    U=${UG%%:*}
    mkdir -p "/home/${G}/${U}/${DATE_DIR}/${DAY_DIR}"
    chown -R "${U}":"${G}" "/home/${G}/${U}/${DATE_DIR}"
done

If a user is member in multiple groups just specify it multiple times in USER_LIST.

Related Question