LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-01-2010, 09:53 AM   #1
rmount
LQ Newbie
 
Registered: Oct 2003
Distribution: CentOS
Posts: 22

Rep: Reputation: 15
Bash while, while... or something.


Hi folks,

I've written a script that fills a disk with a large file and checks the md5 each time. I'm writing a 500GB iso (ubuntu server iso incidentally) over and over coming up with a unique name using `date +%s`. I'm using it to check for disk corruption. I want to run it for several days/weeks.

The problem is, i don't know how to adjust my script to clear the hard drive once it's full and start over. I've managed to get some logic in to that it'll stop when there's about 1gb of free space left (to avoid the script from erroring). Once the while loops ends i want it to delete the files it wrote (there's no critical data on the array so an "rm -rf filldisk*" will be fine) and then start over writting files.

Essentially, i want the script to run forever unless stopped by hand. In the DOS batch world (*shudder*) i'd use a simple goto. After some searching, a goto is frowned upon (and doesn't work in bash). I'm hoping someone can give me some insight.

Here's the code:

Code:
#!/bin/bash

# filldisk.sh
# This script will take a file and copy it to a specified location, over and over until the disk is full
# each copy will be MD5 checked to ensure integrity.
#
# It is recommended that you setup a RAMDisk, copy a file there and use that as the source.  
#

if [ $# -lt 4 ]
then
    echo "";
    echo "filldisk.sh"
    echo "This script fills the disk.  You need to pass commands to it."
    echo "filldisk.sh <sourcefile_fullpath> <destination_fullpath> <mountpoint> <your_email_address>"
    echo "";
    echo "example:";
    echo "filldisk.sh /mnt/ramdisk/bigfile.iso /bigarray /mnt/bigarray you@domain.com"
    echo "";
    echo "A error log is dumped to <destination_fullpath>\filldisk_errorlog.log"
    echo "";
    exit 1
fi

source="$1"
dest="$2"
mountpoint="$3"
email="$4"
drop_cache=`cat /proc/sys/vm/drop_caches`
chksum=`md5sum $1 | awk '{print $1}'`

# Check for source file
if [ ! -e $source ]
then
    echo "";
    echo "ERROR!!  Source file not found"
    echo "";
    exit 1
fi 

# Check for destination path
if [ ! -e $dest ]
then
    echo "";
    echo "ERROR!!  Destination not found"
    echo "";
    exit 1
fi 

# Check for mount
if [ ! -e $mountpoint ]
then
    echo "";
    echo "ERROR!!  Mount point not found"
    echo "";
    exit 1
fi 

# Kill the drop_cache
sync
echo 3 > /proc/sys/vm/drop_caches

# Start copying loop...
while [ `df | grep $3 | awk '{print $4}'` -gt 1000000 ]; do
 		now=`date +%s`
    # echo "$dest/filldisk-$now"
    cp $source $dest/filldisk-$now
    md5sum $dest/filldisk-$now > $dest/filldisk-$now.md5
    dest_chksum=`cat $dest/filldisk-$now.md5 | awk '{print $1}'`
        # Compare Checksum of the destination file and report an error if there's a mismatch
        if [ $chksum != "$dest_chksum" ]
            then 
            echo "CHECKSUM ERROR ON FILE filldisk-$now!"
            echo "CHECKSUM ERROR ON FILE filldisk-$now!" > $dest/filldisk_failures.log
            sendmail -f `hostname`@domain.com $email < $dest/filldisk_failures.log
        fi
    echo Copy complete, checksum calculated.  Remaining free diskspace is `df -h | grep $3 | awk '{print $4}'`
done

# Revert the drop_cache back to old setting
echo $drop_cache > /proc/sys/vm/drop_caches


# done
echo "All done"
As you can see it stops once the disk is full. It works well, but only runs for about 10 hours on a 1.5TB array i'm testing against. I think i need a "while while" loop or something, but i'm having trouble wrapping my brain around it. Thanks for looking.
 
Old 02-01-2010, 10:09 AM   #2
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
Seems like there are a couple of questions mixed together here, so for now, I will try to answer the first one that comes to my mind: A replacement for GOTO (with an example that harkens back to the BASIC days )

Instead of something like:
Code:
LINE10 print "hello"
LINE20 GOTO LINE10
In bash, I would use a function, and an endless loop, since you want this to run forever:
Code:
repeat_me () {
  code in here is INSIDE the function called "repeat_me"
  you write your files, then delete them, and write them again...
  blah blah blah..
  
  if [ disk getting full? ]; then
     DISKFULL='true'; return # this return will return (break out) from the function.
  fi;
} # close of function

# now, let's run that function forever:

while true; do
  if [ "$DISKFULL" = 'true' ]; then
     Do some code to empty the disk, or maybe call another function to empty the disk;
     unset DISKFULL
  fi;

  repeat_me
done
So, the endless loop caused by while true; do will keep calling repeat_me forever.

Does this help?

Sasha

Last edited by GrapefruiTgirl; 02-01-2010 at 04:01 PM. Reason: added some pseudo code.
 
1 members found this post helpful.
Old 02-01-2010, 12:35 PM   #3
rmount
LQ Newbie
 
Registered: Oct 2003
Distribution: CentOS
Posts: 22

Original Poster
Rep: Reputation: 15
Hi Sasha,

Thanks for you input. I believe I understand the loop. I guess you're right and that my question was a little foggy

Piecing things together i see i can put my "while" stuff into a function which will make it easily repeatable. So the main question is, how do i break out of that function (or while loop) to reevaluate and then go back to doing the while loop?

Right now my script will stop if the hard drive fills up. My goal is to make interrupt the while loop at that point, delete the file previously written, then go back to the while loop. Is that possible?
 
Old 02-01-2010, 04:02 PM   #4
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556Reputation: 556
I have added some pseudo-code to my above post, to show how I might do what you want to do (provided I understand you right!) -- if this is unclear what this does, or it isn't what you want, we'll have another stab at it. Let me know how this works for you.

Sasha
 
Old 02-02-2010, 08:48 AM   #5
rmount
LQ Newbie
 
Registered: Oct 2003
Distribution: CentOS
Posts: 22

Original Poster
Rep: Reputation: 15
Excellent, that's exactly what i was looking for. I was playing with a counter (going from 0 to 999) but this works even better. Thank you Sasha!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Using a long Bash command including single quotes and pipes in a Bash script antcore Linux - General 9 07-22-2009 11:10 AM
BASH: instad of echo-ing, I just want to assing to a bash variable... how?? rylan76 Linux - Newbie 9 11-28-2008 08:46 AM
BASH -copy stdin to stdout (replace cat) (bash browser) gnashley Programming 4 07-21-2008 01:14 PM
Bash: Print usage statement & exit; otherwise continue using Bash shorthand operators stefanlasiewski Programming 9 02-07-2006 05:20 PM
why did bash 2.05b install delete /bin/bash & "/bin/sh -> bash"? johnpipe Linux - Software 2 06-06-2004 06:42 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:24 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration