[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 419
  • Last Modified:

Batch file problem

The following batch file does not execute as I thought it would.

REM *** START OF BATCH FILE ***
@echo off
for /f %%a in ('dir /b') do (
echo a= %%a
set abc=%%a
echo abc= %abc%
)
pause
REM *** END OF BATCH FILE ***

Let's say the output of the "dir /b" command is:

file1.txt
file2.txt
file3.txt

The output of my batch file should be:

a= file1.txt
abc= file1.txt
a= file2.txt
abc= file2.txt
a= file3.txt
abc= file3.txt

Instead, I get:

a= file1.txt
abc=
a= file2.txt
abc=
a= file3.txt
abc=

It seems that the line "set abc=%%a" in my batch file fails to properly set the variable.  Any idea why this does not work?
0
EddieF
Asked:
EddieF
  • 2
1 Solution
 
oBdACommented:
Yes; for the shell interpreter, the "for /f" construct is basically one long line. As such, variables in it will only be expanded once, when the line is read. Enter
help set
in a command window, and you'll find a detailed explanation.
There are two ways around this; use the delayed expansion that's available from W2k on; this will give you the "!" to expand variables during run-time:

REM *** START OF BATCH FILE ***
setlocal enabledelayedexpansion
@echo off
for /f "delims=" %%a in ('dir /b') do (
echo a= %%a
set abc=%%a
echo abc= !abc!
)
pause
REM *** END OF BATCH FILE ***

will produce the correct output (note that i added "delims=", otherwise you'll have trouble with filenames containing spaces).
An NT4 compatible way is to call a batch subroutine in the loop:

REM *** START OF BATCH FILE ***
@echo off
for /f "delims=" %%a in ('dir /b') do (
  set abc=%%a
  call :process
)
goto leave

:process
echo abc= %abc%
goto :eof

:leave
pause
REM *** END OF BATCH FILE ***
0
 
EddieFAuthor Commented:
Thanks for the help.  This works great!
0
 
Chris DentPowerShell DeveloperCommented:

DOS isn't the most flexible language in the world... upgrade? ;)

Even if you get it displaying abc properly, which can be done with slightly better variable naming..:

REM *** START OF BATCH FILE ***
@echo off
for /f %%a in ('dir /b') do (
echo a= %%a
set var=%%a
echo var= %var%
)
pause
REM *** END OF BATCH FILE ***

But now all you get is the final value for %%a being echoed back. Bizarre huh?
0
 
Chris DentPowerShell DeveloperCommented:

Oo he's better at this than me ;)
0

Featured Post

Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now