A 'do' statement at the end of my perl script never runs - perl

In my main script, I am doing some archive manipulation. Once I have completed that, I want to run a separate script to upload my archives to and FTP server.
Separately, these scripts work well. I want to add the FTP script to the end of my archive script so I only need to worry about scheduling one script to run and I want to guarantee that the first script completes it work before the FTP script is called.
After looking at all the different methods to call my FTP script, I settled on 'do', however, when my do statement is at the end of the script, it never runs. When I place it in my main foreach loop, it runs fine, but it runs multiple times which I want to avoid since the FTP script can handle having multiple archives to upload.
Is there something I am missing? Why does it not run?
Here is the relivant code:
chdir $input_dir;
#folder_list = <*>;
foreach $file (#folder_list)
{
if($file =~ m/.*zip/)
{
print "found $file\n";
print "Processing Files...\n";
mkdir 'BuildDir';
$new_archive = Archive::Zip->new();
$archive_name = $file;
$zip = Archive::Zip->new($file);
$zip->extractTree('', $build_dir);
&Process_Files;
}
}
do 'ArchiveToFTPServer.pl';
print "sending files to FTP server";
Thanks
I ended up copying and pasting the FTP code into the main file as a sub. It works fine when I call it at the end of the foreach loop.

Check out the docs for the do 'function'.
In there, you'll find a code sample:
unless ($return = do $file) {
warn "couldn't parse $file: $#" if $#;
warn "couldn't do $file: $!" unless defined $return;
warn "couldn't run $file" unless $return;
}
I suggest putting this code in to find out what's happening with your do call. In addition, try adding warnings and strict to your code to weed out any subtle bugs.

Add these lines to your scripts:
use strict;
use warnings;
You will now get more diagnostic information, which should lead you to the solution. My current bet is that you are not specifying the correct path to the other script, or that it is missing a shebang line.

What's the call to the new script? If using a shell, did you check your environment variables?

Related

psftp error flag using in perl

The script below functions just as intended. It calls the batch file which establishes a connection using PUTTY or scpecically psftp and transfers a handful of file. Once the transfer is complete i continue with the perl script to move the files to another directory.
My question is how could I capture an error from the PSFTP application? If there is an error xfering or establishing a connection i would like to generate a flag which then i could capture in perl and stop anything else from happening and send me an email. I just need guidance on generating the flag from the PSFTP application on error.
Thank you very much in advance!
My
use warnings;
use File::Copy;
my $TheInputDir = "//NT6/InfoSys/PatientSurvey/Invision/CFVMC/";
my $TheMoveDir = "//NT6/InfoSys/PatientSurvey/Invision/CFVMC/Completed";
system ('2166_PG_Upload_Batch.bat');
opendir (THEINPUTDIR, $TheInputDir);
#TheFiles = readdir(THEINPUTDIR);
close THEINPUTDIR;
#Get all the files that meet the naming convention
foreach $TheFile(#TheFiles)
{
if($TheFile =~ /2166/)
{
print "$TheFile\n";
move ("$TheInputDir$TheFile","$TheMoveDir");
}
}
You should read STDERR from your application into Perl. For that use Capture::Tiny
my ($stdout, $stderr, $exit) = capture {
system('2166_PG_Upload_Batch.bat');
};
#check for $stderr and do your stuffs i.e sending email etc
For more info refer perlfaq

How to run set of .exe files in a folder through .bat file using perl script

I am beginner to Perl and I have to create a .pl file and I have folder containing near about 30 exe files(inside Folder1 in G:\Folder1). All of them must be executed by click to the .pl file.
My try is :
use strict; use warnings;
use autodie; # automatic error handling
while (defined(my $file = glob 'C:\shekhar_Axestrack_Intern*.exe'))
{
open my $fh, "<", $file; # lexical file handles, automatic error handling
while (defined( my $line = <$fh> )) {
do system $fh ;
}
close $fh;
}
Please let me know if my logic correct ? Could some one please correct me if i am wrong ?
Use system to execute an exe:
while (my $file = glob 'C:\shekhar_Axestrack_Intern\*.exe') {
system $file;
}
In addition, I have the feeling that you meant to write 'C:\shekhar_Axestrack_Intern*.exe'
instead of 'C:\shekhar_Axestrack_Intern*.exe'.
I think pl2bat may help you. It allows you to wrap Perl code into a batch file.
BTW why are you using echo in your Perl script? You should use print.
Edit: You have edited your question and now you want to know how to run all exe files from a folder using Perl?
Use the system command to run the exe files providing the full path.
See: How to run an executable file using Perl on Windows XP?
Edit 2: do system $fh ; This is not how you do it, please get a book (I'd suggest Beginning Perl by Ovid) and start learning Perl.

Unable to open text file in Perl

I am fetching some log files (which are in txt format) from another server and trying to parse them using my Perl script. The logs are being fetched correctly after which I set permissions to 777 for the log directory.
After this I attempt to open the log files, one by one for parsing, via my Perl script. Now, the strange thing and the problem which happens is, my script is sometimes able to open the file and sometimes NOT. To put it simply, it's unable to open the log files for parsing at times.
Also, I have cronned this perl script and the chances of file open failing are greater when it runs via cron rather than manually, although they have run successfully in both cases previously. I don't understand where the issue lies.
Here is the code which I use for opening the files,
$inputDir = "/path/to/dir";
#inputFiles = <$inputDir/*>;
# inputFiles array is list of files in the log directory
foreach my $logFile(#inputFiles)
{
# just to ensure file name is text
$logFile = $logFile."";
# process file only if filename contains "NOK"
if(index($logFile,"NOK") > -1)
{
# opens the file
open($ifile, '<', $logFile) or die "Error: Unable to open file for processing.";
# file parsing takes place
}
}
close($ifile);
I want to re-iterate that this code HAS run successfully and I haven't changed any part of it. Yet, it does not run every time without fail, because its unable to open the log file at times. Any ideas?
You should include the error message $! and the file name $logFile in your die string to see why the open failed, and for which file.
open($ifile, '<', $logFile) or die "Error: Unable to open $logFile: $!";
Also, this line:
$logFile = $logFile."";
...is quite redundant. If a conversion is necessary, perl will handle it.
Just as an example, this is what you code should look like. You may like to try this version
use strict;
use warnings;
my $inputDir = '/path/to/dir';
my #inputFiles = <$inputDir/*>;
foreach my $logFile (grep /NOK/, #inputFiles) {
open my $ifile, '<', $logFile or die qq(Unable to open "$logFile": $!);
# Process data from <$ifile>;
}
Maybe opening some files fails, because your program has too many open files. Your program opens all files in $inputDir and processes them in the loop. After that it closes the last file opened.
EDIT: after reading TLP's comment and reading perldoc -f close and perldoc -f open I see that TLP is right and the filehandle in $ifile is closed by a subsequent open($ifile,'<',$logFile) . However, if the file parsing code not shown by the topic creator creates another reference to $ifile the file handle would stay open.
Moving the call to close into the if block should solve your problem:
$inputDir = "/path/to/dir";
#inputFiles = <$inputDir/*>;
# inputFiles array is list of files in the log directory
foreach my $logFile(#inputFiles)
{
# process file only if filename contains "NOK"
if(index($logFile,"NOK") > -1)
{
# opens the file
# added my to $ifile to keep local to this scope
open(my $ifile, '<', $logFile) or die "Error: Unable to open file for processing.";
# file parsing takes place
# close current file
close($ifile);
}
}

Perl to set a directory to open, open it, then print the directory opened?

Trying to troubleshoot a port of some perl code from CentOS to Windows.
Really know nothing about Perl, and the code I'm porting is around 700-1000 lines. 100% sure one of the issues I'm seeing is related to how the code is being rendered as a result of being on the OS it's running on.
So, I'm looking for a way to troubleshoot debugging how the OS's are rendering filepath apart from the legacy code; which I can not post to SO due to "IP" reasons.
So, I looking for some perl that I can set a directory to open within the script (for example, C:\data\ or /home/data), then script attempts to load the directory, prints if it failed or succeeded, and then prints the string it attempted to load, regardless if the code failed to open the directory or not.
Open to suggestions, but that's the issue, and the solution I'm seeing.
Questions, feedback, requests - just comment, thanks!!
use IO::Dir;
my $dir = IO::Dir->new($dir_path) or
die "Could not open directory $dir_path: $!\n";
of course, where $dir_path is some path to a directory on your system that you want, either as a var or hard coded. The more 'old school' way would look like:
opendir my $dir, $dir_path or die "Could not open directory $dir_path: $!\n";
That won't print of the directory is opened, but the program will fail if it doesn't open it then print the precise error as to why, which is what the $! variable holds.
Is this what you're looking for?
use DirHandle;
my $dir = "test";
my $dh = new DirHandle($dir);
if($dh) {
print "open directory succeeded\n";
}
else {
print "open directory failed\n";
}
print $dir, "\n";
new DirHandle opens the directory and returns a handle to it. The handle will be undef if the open failed.

Perl Linux::Inotify2 - can't respond to events anymore

I am getting some really weird behavior when using Linux::Inotify2 module for watching a directory for any newly created files.
I had made a test script to see how it worked, and once that was done, I went on to incorporating its usage in the other scripts, in which it didn't work. Then, when I tried my earlier test script again to find some information, strangely that stopped working as well. It hasn't worked since then. There were no package/distro upgrades during that time.
The problem is that it has stopped responding to events. Here's the test script:
#!/usr/bin/perl
use strict;
use warnings;
use Linux::Inotify2;
my $inotify = new Linux::Inotify2 or die "unable to create new inotify object: $!";
my $dir = "/my/dir";
$inotify->watch($dir, IN_CREATE, sub {
my $e = shift;
print $e->fullname;
}) or die " Can't watch $!";
1 while $inotify->poll;
A strace on the running script kills the script. Otherwise when strace is used when starting the script, then it does seem to read the new events, but there's no response to those events. Any suggestions for debugging this further ?
I had forgotten to set the $|.