'Why does this cmd oneliner only work the second time it is called?
Consider the following code executed on a Windows (10) cmd (this is actually a simplyfied version of a script that shows an erronous behavior):
type nul >> "a"
set "e=" & for /f "delims=" %F in ('dir /b a') do (set "e=%F" & if not defined e (echo "") else (echo "%e%"))
In short: reset the variable e, loop over files found by dir, make e the current filename, if e is defined, print it.
Run for the first time, it produces the output %e%. When executed a second time in the same shell, it produces a (which is what I would have expected). This doesn't happen when there is no for involved.
What causes this behavior and how do I always get the correct output?
Solution 1:[1]
When CMD.EXE executes a line, it first replaces all variables with the current value for the entire command line. Then it executes the line. Because eisn't defined when the second command is executed, CMD doesn't remove %e%. The second time, the environment variable exists and gets replaced.
%e% is not a variable like in other languages that gets evaluated at the time the interpreter gets to the command.
If you change you sample script to
type nul >> "a"
set e=b
set "e=" & for /f "delims=" %F in ('dir /b a') do (set "e=%F" & if not defined e (echo "") else (echo "%e%"))
the output is b rather than %e% or a because that is the value of e at the time the line is executed.
Solution 2:[2]
The reason for this seems to be the immediate expansion of variables by the cmd. See this post for a nicer description. According to the cmd description (MSDN), cmd contains a flag /v:on that allows delayed variable expansion. Above example then needs to become:
type nul >> "a"
set "e=" & for /f "delims=" %F in ('dir /b a') do (set "e=%F" & if not defined e (echo "") else (echo "!e!"))
This behavior is unexpected at least. The cmd is such a poor environment that it hurts me everytime I have to look at it.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Christof Wollenhaupt |
| Solution 2 | Pascal |
