can't get out of infinite while loop

Discussion in 'Perl Misc' started by monk, Aug 17, 2007.

  1. monk

    monk Guest

    Need your help please.

    This is what it does:
    ---------------------------
    This script takes files out of one directory. Moves the files out of
    the source_dir, puts them into a bridge_dir, adds extension tmp while
    there, then moves the files into the destination_dir removing the tmp
    extension. It checks the source_dir for new files every 10 seconds.

    To get into the infinite loop, I write to a file the "on" status
    (1).

    If it finds the "on" status (1), gets into the loop until that
    condition changes.
    It reads the file every time it gets into the loop to see if the
    condition changed to "off" (0). When you send the --red switch, it
    will write to a file the "off" status (0);

    However, the second time it tries to read the file, it complains
    saying that the file does not exist. What the hell? it just read a
    second ago? Why is it saying that the file isn't there? the file is
    there.

    If you have a better way to get out of the loop please let me know.

    I need wisdom and enlightenment.


    Output
    --------------

    $ perl trafficLight.pl --green
    writing switch on
    switch on written
    reading status file
    condition equals 1
    getting into loop
    inside of loop pass. Reading status file
    ready to sleep for 10 seconds
    inside of loop pass. Reading status file
    Uncaught exception from user code:
    No such file or directory at trafficLight2007817.pl line 145.
    main::do_Green() called at trafficLight2007817.pl line 60



    <code>
    #!/usr/bin/perl

    use warnings;
    use strict;
    use File::Copy;
    use diagnostics;
    use Getopt::Long;
    use Time::localtime;


    my $status_file = "trafficLight.status";

    my $switch_on = "1";
    my $switch_off = "0";



    my $source_dir_path = "/home/monk/source_dir";
    my $destination_dir_path = "/home/monk/destination_dir";
    my $bridge_path = "/home/monk/bridge";


    my $PICKUP_INTERVAL = 10; #seconds expressed in integers
    my $extension = ".tmp"; #extension added to files while on the
    bridge. It can be *.tmp

    #define parameters for the help menu
    my $help = "";
    my $green = "";
    my $red = "";

    GetOptions( 'help' => \$help, 'green' => \$green, 'red' => \$red );

    if ($help) {
    printHelp();
    exit;
    }

    elsif ($green) {
    do_Green();
    exit;
    }
    elsif ($red) {
    do_Red();
    exit;
    }
    else {
    printHelp();
    exit;
    }

    sub printHelp {
    my $help = q{

    Description:
    Processes files from one directory to another.


    Parameters:
    --help [ -h ] [ --h ] : prints this help
    --green [ -g ] [ --green ] : process the files
    --red [ -r ] [ --red ] : stop processing files killing
    the process

    Usage: perl traffic_light.pl [--help\-h\--h] [--green\-g\--g] [--red\-r
    \--r]


    };

    print $help;

    }

    #write status ON to a file for green light
    print "writing switch on\n";
    sleep 7;
    open( SWITCH, "> $status_file" ) or die "Problem writing to
    $status_file file...$!";
    print SWITCH $switch_on;
    close(SWITCH);

    print "switch on written\n";
    sleep 7;
    my $condition;




    sub do_Green {


    #flush my buffers
    #$| = 1;

    print "reading status file\n";
    sleep 5;
    open( SWITCH, $status_file ) or die "Process has been exited already
    $!";

    while (<SWITCH>) {
    chomp;
    $condition = $_;
    }
    close SWITCH;
    print "condition equals $condition\n";
    print "getting into loop\n";
    sleep 7;

    while ( $condition == 1 ) {
    print "inside of loop pass. Reading status file\n";
    sleep 5;
    open( SWITCHAGAIN, $status_file ) or die $!;
    while (<SWITCHAGAIN>) {
    chomp;
    $condition = $_;
    }
    close (SWITCHAGAIN);

    #set up dirhandles
    opendir( SOURCEDIR, $source_dir_path )
    or die "Problem accessing the source directory...$!";

    #get in there
    chdir $source_dir_path;

    #put files in an array skipping the . and .. files
    my @xfiles = grep !/^\./, readdir(SOURCEDIR);

    #we close the dirhandle
    closedir(SOURCEDIR);

    foreach (@xfiles) {
    move( $_, $bridge_path ) or die "Nothing really to worry about.
    Files are moving.";
    }

    ###################
    #add tmp extension

    opendir( BRIDGEDIR, $bridge_path )
    or die "Problem passing files to the bridge directory...$!";
    chdir $bridge_path;

    my @bridge_files = grep !/^\./, readdir(BRIDGEDIR);

    my $old_filename;

    #we rename each file individually
    foreach (@bridge_files) {

    #work only on the files ending in tmp
    if ( $_ !~ m/$extension$/ ) {

    $old_filename = $_;
    rename( $old_filename, $_ . $extension ) or die $!;
    }
    }

    #closing to avoid contamination on next process
    closedir BRIDGEDIR;

    ######################
    #move files from the bridge to the destination directory
    #NOTE that they go into destination directory with the tmp extension

    opendir( BRIDGEDIR, $bridge_path )
    or die "Problem getting files off the bridge directory...$!";
    chdir $bridge_path;

    my @target_files = grep !/^\./, readdir(BRIDGEDIR);

    #we move each file individually
    foreach (@target_files) {
    move( $_, $destination_dir_path ) or die $!;
    }
    closedir BRIDGEDIR;

    #########################
    #now let us remove the tmp extension.
    #on the destination directory

    opendir( DESTINATIONDIR, $destination_dir_path )
    or die "Problem accessing files on the destination directory...
    $!";
    chdir $destination_dir_path;

    my @destination_files = grep !/^\./, readdir(DESTINATIONDIR);

    #we rename each file individually
    foreach my $file (@destination_files) {

    #work only on the files ending in tmp
    if ( $file =~ m/$extension$/ ) {

    #just remove the artificial tmp extension [incl dot] added while
    on the bridge

    my $extension_length = length($extension);
    #my $new_filename = substr( $file, 0, -4 );

    my $new_filename = substr( $file, 0, -$extension_length );
    rename( $file, $new_filename ) or die $!;
    }
    }
    closedir DESTINATIONDIR;


    print "ready to sleep for $PICKUP_INTERVAL seconds\n";

    #picks up files every x seconds
    sleep $PICKUP_INTERVAL;

    }

    print "got out of the loop exiting now";
    exit(0);
    }


    sub do_Red {

    #if currently program executing
    if (-e $status_file){
    #write process id to a file to kill it later when needed.
    print "writting status off";
    sleep 5;

    open( SWITCH, "> $status_file" ) or die "Problem writing to
    $status_file file...$!";
    print SWITCH $switch_off;
    close(SWITCH);

    print "status off written";
    sleep 5;

    print "removing remnant files if still there (possibly move up)\n";
    unlink $status_file or die "$! File removed already";

    }


    print "leave in peace\n";

    exit(0);

    }

    </code>
     
    monk, Aug 17, 2007
    #1
    1. Advertising

  2. monk

    J. Gleixner Guest

    monk wrote:
    > Need your help please.
    >
    > This is what it does:
    > ---------------------------
    > This script takes files out of one directory. Moves the files out of
    > the source_dir, puts them into a bridge_dir, adds extension tmp while
    > there, then moves the files into the destination_dir removing the tmp
    > extension. It checks the source_dir for new files every 10 seconds.
    >
    > To get into the infinite loop, I write to a file the "on" status
    > (1).
    >
    > If it finds the "on" status (1), gets into the loop until that
    > condition changes.
    > It reads the file every time it gets into the loop to see if the
    > condition changed to "off" (0). When you send the --red switch, it
    > will write to a file the "off" status (0);
    >
    > However, the second time it tries to read the file, it complains
    > saying that the file does not exist. What the hell? it just read a
    > second ago? Why is it saying that the file isn't there? the file is
    > there.


    Likely due to one of your many 'chdir'. Print the current
    working directory along with the filename, in the error.

    Maybe a bit shorter example would help. We don't need to see
    your usage, and options, just the shortest amount of code
    showing the problem.

    > If you have a better way to get out of the loop please let me know.


    Simply create the file or remove the file, then test for its existence.
    No need to write/read it.
     
    J. Gleixner, Aug 17, 2007
    #2
    1. Advertising

  3. monk

    monk Guest

    > Likely due to one of your many 'chdir'. Print the current
    > working directory along with the filename, in the error.


    You da man!!

    yeap...it was tripping out with the many chdir
    I just put an absolute path for the file containing the new
    status :eek:ff/on


    And the debugging statements helped me determine that.

    Sometimes I just don't see the forest for the trees.
    That was a very basic mistake on my part. Now I'll get some sleep.

    Thanks again.
     
    monk, Aug 18, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steven

    while loop in a while loop

    Steven, Mar 24, 2005, in forum: Java
    Replies:
    5
    Views:
    2,259
    Tim Slattery
    Mar 30, 2005
  2. Replies:
    5
    Views:
    613
    benben
    Jan 31, 2006
  3. Uday Bidkar
    Replies:
    4
    Views:
    505
    =?ISO-8859-15?Q?Juli=E1n?= Albo
    Dec 12, 2006
  4. Tinku
    Replies:
    5
    Views:
    358
    Chris Dollin
    Jun 10, 2008
  5. Isaac Won
    Replies:
    9
    Views:
    405
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page