LinuxQuestions.org
Review your favorite Linux distribution.
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 08-20-2007, 04:47 PM   #1
michael.barnes
Member
 
Registered: Jan 2007
Location: Dallas, Oregon
Distribution: Ubuntu; Knoppix; DSL; Raspbian
Posts: 30

Rep: Reputation: 0
PERL - foreach array not clearing


Objective: Create a perl daemon which will check a folder for the presence of a file, then move it to another folder based on extension. Extensions in use are .mp3, .wav, .txt.

I kludged together this script:

#!/usr/bin/perl


# Scripts to monitor Enco xfer folder and move the files to
# the proper folders on the Enco side.
#
# I hope!
#
# by Michael Barnes
#
#

use File::Copy;
use POSIX qw(setsid);

chdir '/' or die "Can't chdir to /: $!";
umask 0;
# next 4 lines commented for debugging
# open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
# open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
# open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
# defined(my $pid = fork) or die "Can't fork: $!";
unless(my $pid = fork()) {
exit if $pid;
setsid or die "Can't start a new session: $!";

while(1) {
sleep(5);
print "Hello...\n"; # for debugging
undef (@filelist); # attempt to clear array

@filelist = glob "/mnt/xfer/Enco/xfer/*";
@logs = grep (/txt|TXT/, @filelist); # cull out text files
@mp3 = grep (/mp3|MP3/, @filelist); # cull out mp3 files
@wav = grep (/wav|WAV/, @filelist); # cull out wav files

foreach $_ (@logs) {
push @logfile,$_;
}

foreach $logfile (@logfile) {
$newlogfile = $logfile;
$newlogfile =~ s/\/mnt\/xfer\/Enco\/xfer/\/tmp\/Data\/logs/;
print "'$logfile' and '$newlogfile'\n"; #for debugging
move ($logfile, $newlogfile) or die "Holy moly we got us a log error here hoss!";

}
$logfile = (); # attempt to clear array
undef ($newlogfile); # attempt to clear array

# Following segments for other file types are identical. Deleted for brevity in debugging.
}
}


Problem: Once started, the script runs fine. When some files are placed in the xfer folder they are properly moved to the correct folder and gone from the xfer folder. However, when the script loops through again, it tries to move the files again and crashes on the move since the files are gone.

Thoughts: It seems to me that the arrays are not clearing and are being re-read.

Ideas on fixing this are appreciated.

Thanks
 
Old 08-20-2007, 04:59 PM   #2
gizmo_thunder
Member
 
Registered: Apr 2004
Posts: 101

Rep: Reputation: 15
Quote:
foreach $logfile (@logfile) {
$newlogfile = $logfile;
$newlogfile =~ s/\/mnt\/xfer\/Enco\/xfer/\/tmp\/Data\/logs/;
print "'$logfile' and '$newlogfile'\n"; #for debugging
move ($logfile, $newlogfile) or die "Holy moly we got us a log error here hoss!";

}
$logfile = (); # attempt to clear array
undef ($newlogfile); # attempt to clear array
----------------------------------------------------

In the above piece of code, you are setting the scalar $logfile to () and not the array @logfile
i guess that's the problem, just change the variable name or set @logfile to () and see.

ps: I don't have access to a linux system so could not check it myself.
 
Old 08-20-2007, 05:07 PM   #3
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,125

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
I've had an issue trying to undef an array - might have been the way I was testing.
I use @array = "";

There are probably "better" answer(s).
 
Old 08-20-2007, 05:57 PM   #4
michael.barnes
Member
 
Registered: Jan 2007
Location: Dallas, Oregon
Distribution: Ubuntu; Knoppix; DSL; Raspbian
Posts: 30

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by gizmo_thunder View Post
----------------------------------------------------

In the above piece of code, you are setting the scalar $logfile to () and not the array @logfile
i guess that's the problem, just change the variable name or set @logfile to () and see.

ps: I don't have access to a linux system so could not check it myself.
Give that man a Kewpie doll!! That was it. A simple change from $ to @ and all works well.

Thanks!
 
Old 08-20-2007, 07:33 PM   #5
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,358

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
That's why i never use the same (or too similar) names for scalars and arrays.
Also, the way to clear an array is
@arr = ();

you should do this for all the arrays at the top of the loop, just before (or just after) the sleep().
This block is redundant, you've already got an array of logfiles:

foreach $_ (@logs) {
push @logfile,$_;
}

Personally I always use proper names for loop vars, even if $_ is avail, it's just easier to read/debug, especially as progs get longer/more complex.

Always use

#!/usr/bin/perl -w
use strict;

at the top of your progs.
you can do a test compile/syntax check with
perl -wc yourprog.pl
which will check but not run it.

HTH
 
Old 08-20-2007, 07:45 PM   #6
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,125

Rep: Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120Reputation: 4120
Quote:
Originally Posted by chrism01 View Post
This block is redundant, you've already got an array of logfiles:
Apparently the OP uses common code in the loop for all 3 types.
Yes it might be avoided, but everybody has to develop their own style.
 
Old 08-20-2007, 07:54 PM   #7
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,358

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Well, he's got a generic list of all files: @filelist, then he greps out a sub-list for each type of file; @logs, @wav, @mp3 for processing.
Why copy each sub-list again?
BTW, a simpler way is
@arr1 = @arr2;
 
Old 08-21-2007, 05:46 AM   #8
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
also, your greps are wrong,

e.g. you could have a file named txtwav.mp3

maybe better (with case-insensitive modifier 'i')

Code:
grep { /\.txt$/i } @file_list
it's better to get the habit of using a block for map and grep too, as it keeps
your $_ local when you use it. Otherwise if you do a map with a s/// you might clobber
what you don't mean to.

always localise your $_ in a sub too.

maybe also a block will be compiled once only.
 
Old 08-21-2007, 09:37 PM   #9
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,358

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Filename parsing:

use File::Basename;

$base = basename($path);
$dir = dirname($path);
($base, $dir, $ext) = fileparse($path);
 
  


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
perl + @INC array Ateo Programming 0 01-22-2007 01:38 PM
PERL: Help w/ "foreach" loops and building a Crontab entry - Just need some advice bpmee Programming 5 10-13-2006 02:12 PM
Perl: Where am I in a foreach loop? jrtayloriv Programming 3 01-30-2005 10:43 PM
PERL: Size of an array of an Array inspleak Programming 2 03-10-2004 02:24 PM
perl:foreach katana Programming 3 07-24-2001 01:05 AM

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

All times are GMT -5. The time now is 09:06 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