Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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
share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

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.

share|improve this answer
    
@SkyBeam yes the permission is causing problem now. how do i overcome it? –  Himalay May 26 '11 at 21:34
    
Just add another chown line - I've updated the answer to include chown as well. I guess you won't have to change the group ownership. If you have to, then just use 'chwon -R "${U}":groupname ...' instead. –  SkyBeam May 26 '11 at 21:42
    
@SkyBeam I have two different groups for those two users. Should I do it separately for this adding another for loop? –  Himalay May 26 '11 at 21:54
    
@SkyBeam actually there are three users and two group. I added in question above about that. –  Himalay May 26 '11 at 22:01
    
Although this looks easy it is probably a bit more difficult to answer as you would have to map each user to a group. However as we are talking about home directories most likely the /home/<subdir>/<user> directory already belongs to the right group. So we mighr read it from there? I am going to add an update... –  SkyBeam May 26 '11 at 22:09
show 11 more comments

Use the -p option to mkdir to create more than one element of the path at the time, and use a for-loop to avoid repeating yourself:

sh -c '
  for a in abcd wxyz; do 
    for b in dammi harrami; do 
      mkdir -p /home/$a/$b/$(date +%Y-%m)/$(date +%d); 
    done; 
  done
'

(line-breaks to show logical structure; could be all on one line)

share|improve this answer
    
Good answer. Even a bit faster than me. I like that you loop over home sub-directories too. However in his sample he creates 3 times "harrami" subfolders but dammi is not created within "wxyz" folder. Well, this might be a bug in the initial question though. You might also want to move the $(date) calls out of the loop. The date call is supposed to return the same value for each loop. $() issues a fork which can be very slow when used in loops. –  SkyBeam May 26 '11 at 21:23
    
You can also get away with only one 'date' invocation: $(date "+%Y-%M/%d") –  glenn jackman May 27 '11 at 13:45
add comment

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.