如何生存"延迟的变量扩充"在DOS批处理脚本 [英] How to survive "delayed variable expansion" in a DOS batch script

查看:205
本文介绍了如何生存"延迟的变量扩充"在DOS批处理脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的脚本:

@echo off
setlocal

for /f %%i in ('echo aaa/') do set REPO=%%i
if "%REPO%"=="" (
  echo No input
) else (
  echo %REPO:~-1%
  echo %REPO:~0,-1%
  if %REPO:~-1%==/ set REPO=%REPO:~0,-1%
  echo %REPO%
)

endlocal

请,请注意:

c:\dev\shunra\GlobalLibrary\Server>c:\Utils\hgbackup.cmd
/
aaa
aaa/

c:\dev\shunra\GlobalLibrary\Server>

这是怎么回事?

修改

请注意,那我分配给回购的东西,计算结果为AAA,所以我希望它打印AAA,而不是AAA /。它使我疯了。

Note, that I am assigning to REPO something that evaluates to "aaa", hence I expect it to print "aaa", not "aaa/". It drives me crazy.

EDIT2

显然,这里是(对set命令从帮助)罪魁祸首:

Apparently, here is the culprit (from help on the set command):

Finally, support for delayed environment variable expansion has been
added.  This support is always disabled by default, but may be
enabled/disabled via the /V command line switch to CMD.EXE.  See CMD /?

Delayed environment variable expansion is useful for getting around
the limitations of the current expansion which happens when a line
of text is read, not when it is executed.  The following example
demonstrates the problem with immediate variable expansion:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "%VAR%" == "after" @echo If you see this, it worked
    )

would never display the message, since the %VAR% in BOTH IF statements
is substituted when the first IF statement is read, since it logically
includes the body of the IF, which is a compound statement.  So the
IF inside the compound statement is really comparing "before" with
"after" which will never be equal.  Similarly, the following example
will not work as expected:

    set LIST=
    for %i in (*) do set LIST=%LIST% %i
    echo %LIST%

in that it will NOT build up a list of files in the current directory,
but instead will just set the LIST variable to the last file found.
Again, this is because the %LIST% is expanded just once when the
FOR statement is read, and at that time the LIST variable is empty.
So the actual FOR loop we are executing is:

    for %i in (*) do set LIST= %i

which just keeps setting LIST to the last file found.

Delayed environment variable expansion allows you to use a different
character (the exclamation mark) to expand environment variables at
execution time.  If delayed variable expansion is enabled, the above
examples could be written as follows to work as intended:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "!VAR!" == "after" @echo If you see this, it worked
    )

    set LIST=
    for %i in (*) do set LIST=!LIST! %i
    echo %LIST%

不过,我尝试使用标志,它仍然不为我工作。我用GET 打印屏幕或再次错误的结果上。

But I tried using the ! sign, still it does not work for me. I use get ! printed on the screen or the wrong result again.

推荐答案

正如在评论中进行了讨论,并在您编辑的问题,你需要延迟扩展。

As has been discussed in the comments, and in your edited question, you need delayed expansion.

延迟扩展必须启用,然后才能使用它。在一个批处理脚本可以使用 SETLOCAL enableDelayedExpansion

Delayed expansion must be enabled before you can use it. Within a batch script you can use setlocal enableDelayedExpansion

@echo off
setlocal enableDelayedExpansion

for /f %%i in ('echo aaa/') do set REPO=%%i
if "%REPO%"=="" (
  echo No input
) else (
  echo %REPO:~-1%
  echo %REPO:~0,-1%
  if %REPO:~-1%==/ set REPO=%REPO:~0,-1%
  echo !REPO!
)

endlocal

修改

如果IN()子句被改变使得REPO是不确定的上述失败。例如:(回声)

The above fails if the IN() clause is changed such that REPO is undefined. For example: in (echo.)

它失败,因为整个IF / ELSE构造必须拥有有效的语法,甚至它的ELSE子句不会被执行。

It fails because the entire IF/ELSE construct must have valid syntax, even it the ELSE clause will not be executed.

如果REPO是不确定的,那么

If REPO is undefined, then

if %REPO:~-1%==/ set REPO=%REPO:~0,-1%

扩展到

if ~-1REPO:~0,-1

这是无效的语法。

which is invalid syntax.

问题又是通过使用延迟扩展解决了。

The problem again is solved by using delayed expansion.

@echo off
setlocal enableDelayedExpansion

for /f %%i in ('echo.') do set REPO=%%i
if "%REPO%"=="" (
  echo No input
) else (
  echo %REPO:~-1%
  echo %REPO:~0,-1%
  if !REPO:~-1!==/ set REPO=%REPO:~0,-1%
  echo !REPO!
)

endlocal

这篇关于如何生存"延迟的变量扩充"在DOS批处理脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆