Reputation: 202
For example, this:
ffmpeg -i %1 -c:v libx264 -preset medium -crf 30 -c:a aac "%~n1_OUT.mp4"
Does not need %%1 and %%~n1 respectively.
But this:
FOR /f %%f in ('dir /b .') DO somecommand %%f
Needs %%, otherwise it's not working.
Can somebody explain any logical reason for this chaotic design?
Upvotes: 1
Views: 194
Reputation: 34949
The percent-sign %
is used by cmd.exe
and also its predecessor command.com
to mark expansion1 of environment variables (like %VAR%
), for
-loop meta-variables (like %I
/%%I
), and argument references in batch files (like %1
).
There are two distinct parsing modes, which behave differently when it comes to %
-expansion:
%VAR%
is kept as is when an environment variable VAR
is not set.%
-signs supported, so %%VAR%%
results in %
+ value of VAR
+ %
.%1
.%
-sign is supported in that %%
represents a literal %
.Of course I cannot tell why the developers decided the parser to behave that way, but I believe there are several factors contributing:
for
command was introduced2, the developers decided to use the %
-sign too to mark loop meta-variables, leading to conflicts in command line mode, particularly because empty variables remain: For instance, an expression like %foo%bar
results in the value of foo
+ bar
when variable foo
is set, but otherwise to value of %f
+ oo
+ value of %b
+ ar
when loop variables %f
and %b
exist, and so on. This is particularly because for
parses the command line a second time after the initial potential expansion of environment variables.for
parser probably led to the decision of improved handling of %
-expansion in that undefined variables are treated differently by expanding such to empty strings. In order to still be able to yield literal %
-symbols, escaping like %%
was introduced: For example, a text like 10% plus 20%
could not be returned without escaping since a variable named SPACE + plus 20
is most likely undefined; however, specifying 10%% plus 20%%
results in the literal string 10% plus 20%
.Anyway, the %
-escaping in batch file mode is the intrinsic reason for why for
meta-variables need to be specified like %%I
(in contrast to %I
in command line mode) in order for them to survive the escaping, resulting in %I
, which is then recognised by the for
command parser that comes into play after %
-expansion.
For detailed information about what exactly happens, refer to: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
1) The term expansion means to replace an expression (like %VAR%
) by the string value it refers to (like the one stored in the respective environment variable named VAR
) while parsing.
2) Although I do not know whether the for
command was introduced before or after implementation of the batch file mode.
Upvotes: 2
Reputation: 1360
Command started from console window use single percent sign in for loop varible, but script files uses doubled percent sign. Its by design, well documented. Nothing chaotic..
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/for
Upvotes: 0