这是我的剧本:
@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>
发生了什么事?
修改
注意,我正在为REPO指定一个评估为“aaa”的东西,因此我希望它打印“aaa”,而不是“aaa /”。它让我发疯。
EDIT2
显然,这是罪魁祸首(来自set命令的帮助):
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 !
或错误的结果。
答案 0 :(得分:4)
正如评论和编辑过的问题所讨论的那样,您需要延迟扩展。
必须先启用延迟扩展才能使用它。在批处理脚本中,您可以使用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未定义,则上述操作失败。例如:in (echo.)
它失败了,因为整个IF / ELSE结构必须具有有效的语法,即使它不会执行ELSE子句。
如果未定义REPO,则
if %REPO:~-1%==/ set REPO=%REPO:~0,-1%
扩展为
if ~-1REPO:~0,-1
这是无效的语法。
使用延迟扩展可以解决问题。
@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
答案 1 :(得分:0)
请注意,我正在为REPO分配评估为“aaa”
的内容
实际上,你有条件地分配一些东西。您是否测试过then-part是否实际执行(例如,echo If Entered
)。
答案 2 :(得分:0)
这对我有用(只是我整个剧本的摘录)
choice /C 1234567H /M "Select an option or ctrl+C to cancel"
set _dpi=%ERRORLEVEL%
if "%_dpi%" == "8" call :helpme && goto menu
for /F "tokens=%_dpi%,*" %%1 in ("032 060 064 096 0C8 0FA 12C") do set _dpi=%%1
echo _dpi:%_dpi%: