Link to home
Start Free TrialLog in
Avatar of MarcRosenberg
MarcRosenberg

asked on

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

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;

Avatar of gripe
gripe

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.

SOLUTION
Avatar of gripe
gripe

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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 :(


ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
Avatar of MarcRosenberg

ASKER

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.


SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial