I wrote this script to looking for volume with enough free space:
@echo on
setlocal
set gbsize=1,073,741,824
Set gbsize=%gbsize:,=%
for %%A in (A B C D) do (
for /f "tokens=3,4,5,*" %%B in ('dir %%A:\') do (
set bytesfree=%%B
set bytesfree=%bytesfree:,=%
if %%D == free If %bytesfree% gtr %gbsize% echo hi
)
)
My problem is that the bytesfree variable dosent save its value. the output is(echo is on)
C:\Users\Desktop>(
set bytesfree=**780,607,488**
set bytesfree=**23167987712**
if free == free If 23167987712 GTR 1073741824 echo hi
)
hi
looks like the bytesfree losed its value. Can anyone please help? and provide some explantation? thanks.
To expand on Joey's (original short) answer, the entire for expression is parsed at once, and the % expansion occurs at parse time. But the value you want isn't there until the DO clause has executed. That is why you need delayed expansion. Read the help on for by typing HELP FOR from the command line.
Based on the comment from your previous question https://stackoverflow.com/a/9096601/1012053, it looks like you are attempting to find the drive with the most free space > 1GB.
Your current code has a slight risk of including the wrong line from the DIR command. I've modified it to filter the output using FINDSTR with a regular expression.
EDIT - Also, the IF command cannot properly compare numbers that exceed 2147483647.
So the numbers need to be 0 prefixed and the IF command must be forced to do a string comparison instead of a numeric comparison. I forced a string comparison by enclosing the 0 prefixed number in quotes.
An alternate method using WMIC
Short answer:
Use
instead of just
setlocal
and then use!bytesfree!
to refer to the variable (just replace%
by!
).Longer answer:
This is because
cmd
expands variables as it parses a command, not when the command is run (which, obviously happens after parsing). A command in this case could also be a completefor
statement including the block after it. So all instances of%bytesfree%
within the loop are replaced by their value before the loop, which happens to be an empty string.Delayed expansion is a special form of variable expansion which expands variables when a command is run instead of when parsing it. It can be enabled with
(within a batch file) or
(for a complete session, but not in a batch file, unless you don't want it to resume).
Then the syntax
!bytesfree!
is used to refer to variables which are then expanded just prior to running a command. So when setting and using the same variable within a block (for
loop,if
, etc.) you pretty much always want to use delayed expansion.