Need help for writing shell script

Discussion in 'Programming/Scripts' started by chris_87, Dec 6, 2005.

  1. chris_87

    chris_87 New Member

    Hey guys, I am a new baby here, I need some help in writing a shell script, it basically need to compare the two file contents in xyz time intervals, if the size of source folder is larger, then it will automatically rotate the file to the destination folder, and rename it to folder.1 folder.2, folder.3..etc without overwritting the folder in the destination. Can anyone help me?

    thanks
     
  2. themachine

    themachine ISPConfig Developer ISPConfig Developer

    Perhaps you could be a bit more descriptive... I got a little confused there. Are we talking about *files* or *directories*?

    Maybe if you explained to purpose a little I could give a better example.
     
  3. themachine

    themachine ISPConfig Developer ISPConfig Developer

    Ok, so I played around a little... I don't know how well this will help, but here you go:


    Code:
    #!/bin/bash
    
    # simple script... bla blah
    
    BASE_DIR=/home/johnny/bin/test
    DST_DIR=$BASE_DIR/dir
    SRC_DIR=$BASE_DIR/src_dir
    ROTATED_SUFFIX=`date +"%m%d%y-%H%M%S"`
    
    
    # Move to the base dir
    cd $BASE_DIR
    
    
    # You probably want to test for a newer directory rather than a bigger one
    # -nt = Newer Than
    # You can modify the script to use this condition rather than the 
    # Directory Size
    
    if [ $SRC_DIR -nt $DST_DIR ]; then
            echo "$SRC_DIR is newer than $DST_DIR... It should be rotated!"
            echo
    else
            echo "$SRC_DIR is not newer than $DST_DIR... Don't rotate!"
            echo
    fi
    
    
    # "-e" Tests that $DST_DIR Exists and then gets the 
    # byte count for the directory
    # du -cbs = "Disk Usage -c[total] -b[bytes] -s[supress output]
    # awk gives you just the bytes count, nothing else
    
    if [ -e $DST_DIR ]; then
            DST_BYTES=`du -cbs $DST_DIR | awk '/total/ {print $1}'`
            echo "The destination directory has $DST_BYTES bytes"
    else
            echo "WTF => $DST_DIR doesn't exist!"
            exit 1
    fi
    
    
    # Test for $SRC_DIR and then get the byte count for the directory
    
    if [ -e $SRC_DIR ]; then
            SRC_BYTES=`du -cbs $SRC_DIR | awk '/total/ {print $1}'`
            echo "The source directory has $SRC_BYTES bytes"
    else
            echo "WTF => $SRC_DIR doesn't exist!"
            exit 1
    fi
    
    
    # Test to see if the Source Dir is "Greater Than" the Destination Dir
    # -gt = Greater Than
    # If the SRC_DIR is Greater Than the DST_DIR then it moves
    # The DST_DIR to DST_DIR.[datestamp]-[timestamp]
    # and then copies the SRC_DIR to DST_DIR
    
    if [ $SRC_BYTES -gt $DST_BYTES ]; then
            echo "The source directory is bigger!"
            echo
            echo "Rotating ${DST_DIR} to ${DST_DIR}.${ROTATED_SUFFIX}!"
            mv ${DST_DIR} ${DST_DIR}.${ROTATED_SUFFIX}
            mv $SRC_DIR $DST_DIR
    else
            echo "$SRC_DIR is not greater than $DST_DIR... Not rotating!"
    fi
    
    

    P.S. Bash isn't my strong suit, but you know... a couple minutes and a came up with that... hope it helps.
     
    Last edited: Dec 13, 2005
  4. themachine

    themachine ISPConfig Developer ISPConfig Developer

    If you want it to run say, every hour you could create a cron tab by doing:

    Code:
    Edit your crontab:
    # crontab -e
    
    
    Type this in the file:
    1 * * * * /root/scripts/freshen_dir.sh 2>&1 >> /var/log/freshen_dir.log
    
    You would of course need to name this script "freshen_dir.sh", and mv it to /root/scripts.... change that to whatever you want.


    The "2>&1 >> /var/log/freshen_dir.log" will send all output (errors and std_out) to a log file for review.

    Cheers!
     
  5. chris_87

    chris_87 New Member

    Thank you for your kindly reply, let me try to explain my idea clearer.

    Basically I am going to setup a ftp server, setup one account for incoming files with no download read and delete rights, and setup another for my personal account.

    Once my friend upload files to my 'incoming' account, I want to write a script that would able to compare the 'incoming' folder in the 'incoming account' (ie /home/annoymous/uploader1/incoming) to the 'incoming' foder in my personal account (ie /home/ftp/my_own_personal_account/incoming), if the size of source folder is larger than the destination, it would copy the files to the destination folder, and do nothing if it is smaller.

    I want to do this because I've got some other ftp user, I know I can do it easly from the shell, but the other ftp users have no access to the shell, so I want it to be done automatically for serveral intervals (say 2 times a day).

    Besides, I also need help to write a script that help me the clear all files in a folder (ie /home/annoymous/uploader1/incoming OR /home/annymous/uploader*/incoming in batches), but in this case I will only need to to run manually.

    Many thanks again of reading my 'long' question and I really appreciate your help.
     
  6. themachine

    themachine ISPConfig Developer ISPConfig Developer

    In that case... with little modification that script i posted should be able to work for you... I would recommend using the "timestamp" check rather than checking to see if it is larger... mainly because the newer files could be smaller in size therefore it wouldn't work.

    As far as deleting everything in a directory.... you could just throw that into a cronjob... i.e. -

    Code:
    1 * * * * /bin/rm -rf /path/to/your/directory/* 2>&1 > /dev/null
    

    Put that in the appropriate users crontab (as root rype 'crontab -e -u <username>' and that is all you would need. That line right there will delete everything in '/path/to/your/directory/' but not "directory" itself.

    Hope that helps.
     
  7. ckp212002

    ckp212002 New Member

    themachine,

    i am a newbie too, can u pls explain the following line:

    DST_BYTES=`du -cbs $DST_DIR | awk '/total/ {print $1}'`


    thanks
     
  8. drks

    drks New Member HowtoForge Supporter


    Certainly. Let me break this down:

    DST_BYTES -> The variable we are setting. In Bash scripts you do not set a variable with the leading '$', however you do reference it as '$DST_BYTES' after you set.

    `` -> The Backtick '`' (the one on the same key as tilde '~') signifies the execution of code. Bash will spawn a sub-shell, and anything within the back ticks will be executed. The output of the command is sent back, and becomes the value of our variable 'DST_BYTES'.

    du -cbs $DST_DIR -> The 'du' bash command is used to show 'disk usage'. Therefore we are checking the disk usage of the directory $DST_DIR.

    | -> The Bash pipe operator '|' (on the same key as the backspace) is used to pipe the output of the first command, and send it as arguments of the next command (awk).

    awk '/total/ {print $1}' -> Awk is a beast to grand to explain in a simple one liner. However this command is doing a regular expression match for the line that has 'total' in it. Once it has that line, it prints the first ($1) word in that line.
     

Share This Page