问题 | Issue/Problem/Question
我在 FOR 循环中用 SET 为一个环境变量赋值,结果发现该变量始终为空内容,不知何故
比如在下面的代码中:
1、第一个 for 语句我是打算取得 YYMMDD 格式的日期字符串: TODAY_FOLDER,在 for 语句内部的 SET TODAY_FOLDER 语句得不到 TODAY 的值,然而如果放在 for 语句后面就可以
2、第二、第三两个嵌套 for 语句我打算得到一组 IP 地址,然而 echo 用户端IP是%THE_CLIENT_IP% 得到的仍然是空的
代码:
@echo off
REM *******************************
REM FileName: test.cmd
REM OS: Windows 2000 Professional
REM Author: "刘研|LiuYan"
REM DATE: 2006年04月06日 | 04/06/2006
REM *******************************
setlocal
FOR /F "tokens=1-3 delims=- " %%i IN ('date /t') DO (
SET TODAY=%%i%%j%%k
SET TODAY_FOLDER=%TODAY:~2%
echo 今天的文件夹:%TODAY_FOLDER%
)
REM IP 段:15?-18?,其中 ? 取值范围 [1-9](因每排只有 9 个)
for /L %%i in (5,1,8) do (
for /L %%j in (1,1,9) do (
SET THE_CLIENT_IP=192.168.115.1%%i%%j
echo %ERRORLEVEL% ClientIP=[%THE_CLIENT_IP%] 192.168.115.1%%i%%j
)
)
endlocal
@echo on
解决方法 1 | Solution 1
- 修改批处理脚本:在 for、if 语句体中,如果要使用在本语句体由 SET 命令设置的“局部”环境变量,则需要使用 !环境变量名! 的形式来取得它的值,而不能使用传统的 %环境变量名% 形式
- 启动一个单独 cmd.exe 实例来启动该批处理脚本,并在 cmd.exe 启动参数中添加 /V:ON 选项,只有打开 /V:ON 选项,才能使得 !环境变量名! 形式的取值生效。如果需要,可添加 /C 参数使 cmd.exe 在执行完后自动退出
修改后的代码
代码:
@echo off
REM *******************************
REM FileName: test2.cmd
REM OS: Windows 2000 Professional
REM Author: "刘研|LiuYan"
REM DATE: 2006年04月06日 | 04/06/2006
REM *******************************
echo 必须启用 cmd.exe 的 /V:ON 选项 ^| You must open the /V:ON swith/option of cmd.exe
setlocal
FOR /F "tokens=1-3 delims=- " %%i IN ('date /t') DO (
SET TODAY=%%i%%j%%k
SET TODAY_FOLDER=!TODAY:~2!
echo 今天的文件夹:!TODAY_FOLDER!
)
for /L %%i in (5,1,8) do (
for /L %%j in (1,1,9) do (
SET THE_CLIENT_IP=192.168.115.1%%i%%j
echo ClientIP=[!THE_CLIENT_IP!] 192.168.115.1%%i%%j
)
)
endlocal
@echo on
执行该批处理文件
C:\>cmd /V:ON /C test.cmd
解决方法 2 | Solution 2
或者,如果你不喜欢 /V:ON 选项/参数,那么可以试试:CALL 另外一个脚本
修改后的代码
代码:
@echo off
REM *******************************
REM FileName: test3.cmd
REM OS: Windows 2000 Professional
REM Author: "刘研|LiuYan"
REM DATE: 2006年04月06日 | 04/06/2006
REM *******************************
setlocal
FOR /F "tokens=1-3 delims=- " %%i IN ('date /t') DO (
CALL :label_Sub_SetTodayFolder %%i %%j %%k
REM 不过,下面这一句仍然无法得到 TODAY、TODAY_FOLDER 的值
REM echo 今天是:%TODAY%,今天的文件夹:%TODAY_FOLDER%
)
for /L %%i in (5,1,8) do (
for /L %%j in (1,1,9) do (
CALL :label_Sub_SetClientIP %%i %%j
)
)
endlocal
@echo on
@goto :EOF
:label_Sub_SetTodayFolder
SET TODAY=%1%2%3
SET TODAY_FOLDER=%TODAY:~2%
echo 今天是:%TODAY%,今天的文件夹:%TODAY_FOLDER%
goto :EOF
:label_Sub_SetClientIP
SET THE_CLIENT_IP=192.168.115.1%1%2
echo ClientIP=[%THE_CLIENT_IP%]
goto :EOF
总结/说明 | Summary/Description
该问题起因于未启用 cmd.exe 的 /V:ON 选项(cmd.exe 默认的是 /V:OFF),/V:ON 选项将禁用“环境变量的延迟生效”,如果不启用该选项,则环境变量在诸如 if、for 语句体内的值不会实时的取得
参考文档 | References
- C:\>help cmd
- (Windows2000 Command Processor FAQ) 列举了很多例子 http://www.microsoft.com/technet/prodtechnol/Windows2000serv/support/FAQW2KCP.mspx
(WindowsXP cmd) http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/cmd.mspx?mfr=true
(WindowsServer2003 cmd)
http://www.microsoft.com/technet/prodtechnol/windowsserver2003/zh-chs/library/ServerHelp/d0518719-7154-49b4-954c-0a6c015ab441.mspx?mfr=true
- (CSDN上本人发的求助帖,感谢 meidog(meidog)、spark_li(晕忽忽(恶人谷:通讯连长)) 两位热心 csdn 网友的帮助) http://community.csdn.net/Expert/topic/4661/4661135.xml
发表于 @ 2006年04月06日 11:46:00|评论(loading...)|编辑