Variables are not behaving as expected

不想你离开。 提交于 2019-11-25 21:34:19

问题


I\'ve been wrestling trying to get the syntax right on this batch file and I cannot figure out why some things aren\'t working.

  1. The variable i is not getting incremented each time I do it.
  2. Concatenation on strc doesn\'t seem to concatenate.

Here is my code:

set i=0
set \"strc=concat:\"

for %%f in (*.mp4) do (
    set /a i+=1
    set \"str=intermediate%i%.ts\"

    set strc=\"%strc% %str%|\"

    ffmpeg -i \"%%f\" -c copy -bsf:v h264_mp4toannexb -f mpegts \"%str%\"
)

set strc=\"%strc:-1%\"
ffmpeg -i \"%strc%\" -c copy -bsf:a aac_adtstoasc Output.mp4

回答1:


You are not the first, who fell into the famous "delayed expansion trap" (and you won't be the last).

You need delayed expansion if you want to use a variable, that you changed in the same block (a block is a series of commands within brackets (and )).

Delayed variables are referenced with !var! instead of %var%.

Reason is the way, cmd parses the code. A complete line or block is parsed at once, replacing normal variables with their value at parse time. Delayed variables are evaluated at runtime.

Two simple batch files to demonstrate:

setlocal EnableDelayedExpansion
set "var=hello"
if 1==1 (
    set "var=world"
    echo %var% !var!
)
setlocal EnableDelayedExpansion
for /L %%i in (1,1,5) do (
    echo %random% !random!
)

Note: A line is also treated as a block:

set "var=old"
set "var=new" & echo %var% 

With delayed expansion:

setlocal EnableDelayedExpansion
set "var=old"
set "var=new" & echo !var! 

Delayed expansion is per default turned off at the command prompt. If you really need it, you can do:

cmd /V:ON /C "set "var=hello" & echo !var!"

Also there is a way to do the same without delayed expansion (but call costs some time, so it's slower, but if for some reason you can't / don't want to use delayed expansion, it's an alternative):

setlocal DISabledelayedexpansion
for /L %%i in (1 1 5) do (
    call echo %random% %%random%% 
)

Both methods can also be used to display array-like variables:

(This is often asked like "variable which contains another variable" or "nested variables")

Here is a collection for using such array-like variables in different situations:

With delayed expansion:

setlocal ENableDelayedExpansion
set "num=4"
set "var[%num%]=HELLO"
echo plain delayed: !var[%num%]!
for /L %%i in (4 1 4) do (
    echo for delayed: !var[%%i]!
    set a=%%i
    call echo for delayed with variable: %%var[!a!]%%
)

without delayed expansion:

setlocal DISableDelayedExpansion
set "num=4"
set "var[%num%]=HELLO"
call echo plain called: %%var[%num%]%%
for /L %%i in (4 1 4) do (
    call echo FOR called: %%var[%%i]%%
    set a=%%i
    call echo FOR called with variable: %%var[%a%]%%
)

Note: setlocal has no effect outside of batchfiles, so delayedexpansion works only:
- In batch files
- When the cmd was started with delayed expansion enabled (cmd /V:ON) (by default, the cmd runs with delayed expansion disabled)



来源:https://stackoverflow.com/questions/30282784/variables-are-not-behaving-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!