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;
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;
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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 :(
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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.
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(vbNullStrin g, cmdline$, 0&, 0&, 1&, _
&H20&, 0&, vbNullString, start, proc)
' Wait for the shelled application to finish:
lngRetcode = WaitForSingleObject(proc.h Process, INFINITE)
Call GetExitCodeProcess(proc.hP rocess, 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.
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(vbNullStrin
&H20&, 0&, vbNullString, start, proc)
' Wait for the shelled application to finish:
lngRetcode = WaitForSingleObject(proc.h
Call GetExitCodeProcess(proc.hP
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.