Solved

Capturing / Setting Return Value From a Pearl Script to a DOS Bat file

Posted on 2004-10-01
7
1,091 Views
Last Modified: 2008-01-09
I execute the following Dos.bat file (readfile.bat) which in turn runs a PerlScript (ReadFile.PL)
ReadFile simply opens a file and copies it to a second file and keeps a recordcount.
My problem is that the %errorlevel% value in the Dos bat file is not the same value which I exit or print to STDERR from the Perl script.

Any ideas?  Can someone please explain if the correct method is to use Exit $nn or do I need to do something else? The file has 120846 records but the %errorlevel% is coming back as 4776.

I'm confused and desperate. Please help !!! Thanks.

BEGIN CODE:ReadFile.Bat
===================
@echo off
perl C:\Data\ReadFile.pl %*
echo %errorlevel%
END BATCH FILE


BEGIN PERL SCRIPT
===============
#readfile.pl
$filenameIN = $ARGV[0];;
$filenameOUT = $ARGV[1];;
open (INFILE, "$filenameIN") || die "Can't open input file: $!";
open(OUTFILE, ">$filenameOUT") || die "Can't open input file: $!";
$nn = 0;

while (<INFILE>){
print OUTFILE;
$nn++;
}

close (INFILE);
close (OUTFILE);
unlink $filenameIN;
print $nn;
exit $nn;

0
Comment
Question by:MarcRosenberg
  • 4
  • 2
7 Comments
 
LVL 13

Expert Comment

by:gripe
ID: 12205017
Your code works unedited here. It's possible that you're overwriting the values you're printing out because you're not terminating your print statements with a newline "\n". Note the following test:

 C:\temp>type ReadFile.bat
@echo off
perl C:\temp\readfile.pl %*
echo %errorlevel%

C:\temp>type readfile.pl
#readfile.pl
$filenameIN = $ARGV[0];;
$filenameOUT = $ARGV[1];;
open (INFILE, "$filenameIN") || die "Can't open input file: $!";
open(OUTFILE, ">$filenameOUT") || die "Can't open input file: $!";
$nn = 0;

while (<INFILE>){
print OUTFILE;
$nn++;
}

close (INFILE);
close (OUTFILE);
unlink $filenameIN;
print $nn;
exit $nn;



C:\temp>perl -wle"print qq{$_} for 1..2000"  > test.txt

C:\temp>ReadFile.bat test.txt test2.txt
20002000

C:\temp>

As you can see above, the output from both the 'print $nn;' Perl statement and the 'echo %errorlevel%' are both '2000'. Since the perl print is not terminated with a newline, they appear on the same line.

I would say something else is wrong if you're not seeing similar behaviour.

0
 
LVL 13

Assisted Solution

by:gripe
gripe earned 200 total points
ID: 12205078
Ah ha, after writing that I had an epiphany and tried the same test with a file with more records...

It looks like the %errorlevel% variable has a 16 bit (IE: 65535 values) limit to the values it holds and will overflow when given a larger number. Note the following test:

C:\temp>echo %errorlevel%
65535

C:\temp>perl -wle"exit 65536;"

C:\temp>echo %errorlevel%
0

C:\temp>perl -wle"exit 65537;"

C:\temp>echo %errorlevel%
1

C:\temp>

You'll need to think of a different way of returning your value to your calling batch program.
0
 
LVL 18

Expert Comment

by:kandura
ID: 12205094
gripe,
the problem is that passing a value greater than say 16348 through %errorlevel% doesn't work. What we need is a way to capture the return value from the perl script in a variable.
Unfortunately I know nothing of dos or vb :(


0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 18

Accepted Solution

by:
kandura earned 300 total points
ID: 12205144
for /f %%a in ('perl perl C:\Data\ReadFile.pl %*') DO SET RECORD_COUNT=%%a
echo Record count is %RECORD_COUNT%
0
 
LVL 18

Expert Comment

by:kandura
ID: 12205311
uhm, one "perl" is enough there...
anyway, that catches the output from the script in RECORD_COUNT.
In this example, only the last printed line survives, so you should get the $nn from the print statement.
0
 
LVL 2

Author Comment

by:MarcRosenberg
ID: 12218411
gripe and kandura:

I would like to thank you both for solving this problem. I never would have suspected this issue with %ErrorLevel% being limited to 16 bit values. I have implemented kandura's batch commands and am sucessfully retrieving the %Record_Count% variable back to Readfile.bat.

If I may ask for one last piece of assistance and one question....

I am still not able to get the handle to the %Record_Count% variable back to my VB code.

I am exiting Readfile.bat with
exit /b %RECORD_COUNT%

The VB code shells out to Readfile.bat using WIN32 API's contained in a function ExecCmd

Public Function ExecCmd(cmdline$)

   ' Start the shelled application:
   lngRetcode = CreateProcessA(vbNullString, cmdline$, 0&, 0&, 1&, _
      &H20&, 0&, vbNullString, start, proc)

   ' Wait for the shelled application to finish:
      lngRetcode = WaitForSingleObject(proc.hProcess, INFINITE)
      Call GetExitCodeProcess(proc.hProcess, lngRetcode)
      Call CloseHandle(proc.hThread)
      Call CloseHandle(proc.hProcess)
      ExecCmd = lngRetcode
End Function


It always returns a zero. Upon doing some research I found that GetExitProcessCode always returns a zero for 16-Bit Processes. Does this explain the problem? Do bat files run in a 16 Bit process? I suspect not because of the declaration below which references kernel32....

Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
      lpApplicationName As String, ByVal lpCommandLine As String, ByVal _
      lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
      ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
      ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As String, _
      lpStartupInfo As STARTUPINFO, lpProcessInformation As _
      PROCESS_INFORMATION) As Long


As for my question... could you please explain what the /f  switch is doing in your command:
for /f %%a in ('perl C:\Data\ReadFile.pl %*') DO SET RECORD_COUNT=%%a

Thanks very much for your assistance. I will award you both points for the work you have done so far.


0
 
LVL 18

Assisted Solution

by:kandura
kandura earned 300 total points
ID: 12219324
MarcRosenberg,

> I am still not able to get the handle to the %Record_Count% variable back to my VB code.

The problem is that you're going about it in the wrong way, and I suppose we should have noticed that earlier on. The process exit code is always numerical, and only used to indicate whether the process ended successfully or with an error. 0 means success, and a non-zero should map to a (documented) error condition.
The situation is the same as in perl with system versus backticks: you can not capture the output from a "system" command, you need to use backticks or pipes (a la open my $pipe, " |some_command" ).
We managed to capture process output in a batch file, which is nice, but now you still need to know how to do it in VB. The fact that you're now CreateProcess'ing a bat file instead of a perl file makes no difference.

I did a bit of googling (on <<"Visual Basic" capture command output>>), and found one way that uses pipes (which it connects to the stdout and stdin of the process). You can find the code here: http://www.freevbcode.com/ShowCode.Asp?ID=3957
Note that I neither wrote it nor tested it, so please review carefully.


> As for my question... could you please explain what the /f  switch is
> doing in your command:
> for /f %%a in ('perl C:\Data\ReadFile.pl %*') DO SET RECORD_COUNT=%%a

What it stands for, I don't know. Try "help for" in a dos prompt to see it described in your language (mine is dutch, so I won't paste that here ;^)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Perl efficient DB Call 8 96
Perl output collect 7 69
add a syntax to a csv file 8 99
perl script to search for files containing text 3 89
I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

740 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question