Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

problems with perl script

Status
Not open for further replies.

enni

Technical User
Oct 30, 2003
5
EE
Hi,

I'm quite newbie in perl world. I need to create perl script in unix system to analyse original file and after that replace footer with empty line, and after that execute system command..

So far i have problems replace footer with empty line and writing modifications into new file . Here is my script.


open(RAW, "$file");

while(<RAW>) {
chomp;
$trailer = 0;
$line = $_."\n";

if ($line =~ m/TRAILER/){

$trailer = 1;
}
}

unless ($trailer == 1){
$error = "Error message. \n";
&error_msg($error);
die $error;
}

close (RAW);

&write_status("making copy of raw mnp file\n");

system("cp $file $tmp_file");

//this doesn't work
sub write_mnp_trailer {

$line=$_;

open (IN, "< $tmp_file");
open (OUT, ">$mnp_file");

while(<IN>){
chomp;
if($rida =~ m/TRAILER/){
$rida =~ s/TRAILER//;
$trailer = 1;
}
print (OUT "$_\n");
}
close IN;
close OUT;

}
die;

&write_status("checking file\n");

$state = 0;
$i = 0;


&write_status("Starting uploading mnp tables )\n");

while ($state != 1){

if($i > 4){

$error = "Script tried more than 5 times :((\n";
&error_msg($error);
die $error;
}

system(". load_param $mnp_file"." 1>program.stdout 2>program.stderr");


open(OUT, "program.stdout");

while(<OUT>) {

chomp;
$line = $_;

if ($line =~ m/OK/){

$state = 1;
}
}

close (OUT);

$i++;
}

&write_status("finished, files writed into archive\n");

system("mv $mnp_file $file_arch");
...

I
 
A couple of critiques first, before I try and answer the question.

Rather than use system calls for fileio, try and use the perl implementations, as they call C rotuines directly and are much quicker and more reliable than system calls.

Where possible try and write generic functions to handle repeated code. Even a few line sub can make the rest of the code clearer. In the generic routines you can make more robust error handling applicable everywhere, rather than having to cut-n-paste all the time.

Try and use warnings and strict in your code. It can help you spot errors and potential errors a lot quicker. To do this simply start your scripts as:

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

Try and format your code, with appropriate levels of indentation and grouping associated lines together. Using too much whitespace can make the code harder to follow.

Okay on to your problem. In your example you highlight a routine, write_mnp_trailer(), that doesn't work. However, in the script extract you don't call it, and after the function there is a 'die;' which will stop further processing. Was the die left in from debugging, and should the routine be called, or have you wrapped the code up to help with debugging?

The following is mostly a code tidy/simplification to help identify the problem you are having:

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

use File::Copy;
use IO::File;
use Carp;

# check file has a TRAILER keyword
my $fh_raw = open_file("$file");
my $trailer = 0;
while(<$fh_raw>) {
	$trailer = 1	if(/TRAILER/);
}
$raw->close;
error_handler("Error message. \n")	unless ($trailer == 1);

write_status("making copy of raw mnp file\n");
copy($file,$tmp_file);

# generic open file routine, with error handling
sub open_file {
	my $file = shift;
	my $fh = IO::File->new("$file");
	die "Cannot open open file [$file]: $!\n"	unless($fh);
	return $fh;
}

# generic error handler
sub error_handler {
	my $msg = shift;
	error_msg($msg);
	carp($msg);
}

# copying file without TRAILER line
my $fh_tmp = open_file("$tmp_file");
my $fh_out = open_file(">$mnp_file");
while(<$fh_tmp>){
	last	if(/TRAILER/);
	print $fh_out $_;
}                    
$fh_tmp->close;
$fh_out->close;

write_status("checking file\n");
my $state = 0;
my $tries = 0;

write_status("Starting uploading mnp tables )\n");
while (!$state){
    error_handler("Script tried more than 5 times :((\n")	if($tries > 4);
    system(". load_param $mnp_file"." 1>program.stdout 2>program.stderr");
    
	my $fh_out = open_file("program.stdout");
    while(<$fh_out>) {
        $state = 1	if (/OK/);
    }
    $fh_out->close;
    $tries++;
}

write_status("finished, files writed into archive\n");
rename $mnp_file, $file_arch;

Note1: I have added open_file() and error_handler() routines to keep your code easier to read.
Note2: I have use IO::File to read files as this module is very robust at handling any problems that you may encounter with file handling.
Note3: The inline function rename is used in place of system("mv").
Note4: File::Copy use to handle the copy feature.
Note5: I've assumed you didn't mean to create the sub write_mnp_trailer and leave the die in there. I've also assumed that you meant the 'rida' variable to refer to the current line.

I hope that gives you a clearer picture as to where the problems might be.

Barbie
Leader of Birmingham Perl Mongers
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top