Reads commands from an external file

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
th4n4t0s
Posts: 5
Joined: 16 Aug 2011 13:25

Reads commands from an external file

#1 Post by th4n4t0s » 16 Aug 2011 13:31

Hi guy's,
I work an a project and I have some problems to load commands from a file (drag/drop) like that:
example_cmd_file.bat

Code: Select all

@echo off
start calc.exe
pause


my_script_to_read_the_file.bat

Code: Select all

@echo off
setlocal enabledelayedexpansion
set linz=0 & for /F "tokens=* delims=" %%b in ('type %~1') do set /a linz+=1
echo ^>^>^> Debug:^> Lines^=  !linz!
< "%~1" (
   for /L %%c in (1,1,!linz!) do (
      set /p line%%c=
   )
)
for /L %%w in (1,1,!linz!) do (
   !line%%w!
)
pause


Some ideas?
Thanks.

OJBakker
Expert
Posts: 89
Joined: 12 Aug 2011 13:57

Re: Reads commands from an external file

#2 Post by OJBakker » 16 Aug 2011 14:30

In 'example_cmd_file.bat' remove the @ sign from the echo line

I don't know why the @ prefix in @echo off causes the unknown command error

OJB

th4n4t0s
Posts: 5
Joined: 16 Aug 2011 13:25

Re: Reads commands from an external file

#3 Post by th4n4t0s » 16 Aug 2011 14:36

Thanks for the reply.
I've did it but my script wont work if 'example_cmd_file.bat' contains a for loop, therefore I'm asking for some help...

th4n4t0s
Posts: 5
Joined: 16 Aug 2011 13:25

Re: Reads commands from an external file

#4 Post by th4n4t0s » 16 Aug 2011 14:39

("If" conditions doesn't work too, and I've not tried all commands.)

OJBakker
Expert
Posts: 89
Joined: 12 Aug 2011 13:57

Re: Reads commands from an external file

#5 Post by OJBakker » 16 Aug 2011 14:55

The code in your original post is working.
Try again with the code you posted and just remove the @ sign.
If it does not work be more specific.
Post your test code and output.

OJB

th4n4t0s
Posts: 5
Joined: 16 Aug 2011 13:25

Re: Reads commands from an external file

#6 Post by th4n4t0s » 16 Aug 2011 15:03

Here is an example of test code:

Code: Select all

@echo off
if "%USERNAME%"=="aaa" echo Ok
for /L %%i in (0,1,3) do echo Line%%i
ping google.com -n 2
set alpha=Test
echo %alpha%
pause


Output:

Code: Select all

>>> Debug:> Lines=  7
'@echo' is not recognized as an internal or external command,
operable program or batch file.
'if' is not recognized as an internal or external command,
operable program or batch file.
'for' is not recognized as an internal or external command,
operable program or batch file.

Pinging google.com [74.125.39.106] with 32 bytes of data:
Reply from 74.125.39.106: bytes=32 time=36ms TTL=49
Reply from 74.125.39.106: bytes=32 time=37ms TTL=49

Ping statistics for 74.125.39.106:
    Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 36ms, Maximum = 37ms, Average = 36ms
%alpha%
Press any key to continue . . .


I'ts very strange because when you do like that it's works:

Code: Select all

@echo off
set /p cmd=^>cmd:
%cmd%
pause

And when command comes from a file, errors errors errors... :/
Thanks.

jeb
Expert
Posts: 1042
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Reads commands from an external file

#7 Post by jeb » 16 Aug 2011 16:12

Hi th4n4t0s,

the problem is the block

Code: Select all

for /L %%w in (1,1,!linz!) do (
   !line%%w!
)


You try to execute the content with !line%%w! (delayed expansion), but this can't work as the parser has reached a phase where @echo of IF and FOR can't be handled anymore.

You could try something like

Code: Select all

for /L %%w in (1,1,!linz!) do (
   set "currentLine=!line%%w!"
   call :execute
)
...
:execute
%currentLine%


But even this can't work with lines which contains percent expansions like
echo %path%
As result it prints %path% instead of the content

jeb

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Reads commands from an external file

#8 Post by dbenham » 16 Aug 2011 16:14

Ok - we are now in macro territory: a subject near and dear to my heart :D
(by macro I mean storing commands in variables and then executing the variable)

Because of how the batch parser works, FOR and IF commands within variables cannot be executed using delayed expansion (!cmd!). You must use immediate expansion (%cmd%).

But you have additional problems.

Your method for determining the number of lines will fail if there is a blank line because FOR /F ignores blank lines. It will also fail if a line begins with ; because of the default EOL value (though this is unlikely in a bat file).

You can't simply replace ! with %% in your execution phase because %%line%%w%% will not expand properly.

This code gets you closer:

Code: Select all

@echo off
setlocal disableDelayedExpansion
for /f %%a in ('type "%~1"^|find /c /v ""') do set linz=%%a
echo ^>^>^> Debug:^> Lines^=  %linz%
<"%~1" (
  for /l %%c in (1 1 %linz%) do (
    set /p line=
    call :execute
  )
)
pause
exit /b

:execute
%line%
exit /b

But it still has major problems:

1) Still cannot execute FOR commands because FOR variables need to be %%A in batch file, but in the macro definition you only want %A. Trying to figure out which %% need to be converted to % sounds like a parsing nightmare.

1A) There are probably additional syntax issues where the code needed for a batch file is not exactly what you want in a macro.

2) If the batch file enables delayed expansion, it will be terminated by the implicit ENDLOCAL that occurs when the CALL returns. Subsequent delayed expansion of things like !var! will then fail.

3) Any multi line block such as the following will fail:

Code: Select all

if 1==1 (
  echo line 1
  echo line 2
)

4) GOTO :label will fail

5) CALL :label will fail

2) and 3) can be solved by loading the entire batch file into a variable with line feeds between the lines, and then execute the entire thing. This can be done as long as the file is < ~8k. But it hardly seems worthwhile because of the many other problems.

I think the concept of this project is ill advised.

Dave Benham

th4n4t0s
Posts: 5
Joined: 16 Aug 2011 13:25

Re: Reads commands from an external file

#9 Post by th4n4t0s » 16 Aug 2011 16:35

Thanks jeb and Dave Benham for yours explanations.
Actually I just try to make a "batch scripts debugger", but It's looks like impossible (for the moment) to execute commands from an external file step by step (pause betweed two lines) :?

jeb
Expert
Posts: 1042
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Reads commands from an external file

#10 Post by jeb » 18 Aug 2011 13:15

th4n4t0s wrote:Actually I just try to make a "batch scripts debugger", but It's looks like impossible (for the moment) to execute commands from an external file step by step (pause betweed two lines) :?


Nothing is impossible, you only have to change the conditions :wink:

You could try something like copy the target file to a new temporary file and insert after each line a call to your debugger.

Code: Select all

@echo off
echo test
goto :label
echo end


Code: Select all

@echo off
call :debugger 1
echo test
call :debugger 2
goto :label
call :debugger 3
echo end
call :debugger 4


Now call's, goto's and FOR's should work and you can pause after each line

jeb

Post Reply