前言全局说明
今天在写bat脚本时,一个if里的部分代码不执行。
一、说明
1.1 环境:
Windows 7 旗舰版
二、错误结果
2.1 错误结果图片
2.2 错误结果代码
@echo offset updata_conf_flag=False@REM 检查adb_PATH变量是否空
:input_adb_PATH
if "%adb_PATH%" == "" (set /p "adb_PATH=[ INPUT ] 请输入adb路径:" if "%adb_PATH%" == "" ( echo ----adb_PATH=%adb_PATH%@REM 再次检查是否为空 goto input_adb_PATH) @REM bug:上面内容执行了,下面2句内容没有执行,为什么?set updata_conf_flag=True echo 1updata_conf_flag1=%updata_conf_flag%
)
echo aldkfjif "%updata_conf_flag%" == "True" (echo updata_conf_flag1=%updata_conf_flag%
) else (echo updata_conf_flag2=%updata_conf_flag%
)@REM
echo. && echo. && echo. && pause
三、问题分析
3.1 正常过程
按上面代码里执行,正常结果,第16行应该会输出echo的相关内容。
3.2 出现问题
第8-13行执行后,第15、16行没有执行,就直接跳到 18行执行
3.3 问题排查
确认后、不是语法错误、也不是变量名和关键字重名。
既然第8-13行执行会,把15、16行挪到9行之前,得到结果也能执行,排除15、16行语法或其他问题。
那么,很明显,问题出在9-13行。看到结果,输出了"----adb_PATH=", 说明已经进入到了 10-12行执行了。
奇怪,上面提示输入的时候,已经输入了,但是为什么判断还为空?
而且还有个问题,既然判为空应该执行到 goto 跳到标签处(第6行),再次提示用户输入,可是没有跳到第6行,而是跳出,直接到了18行?
3.4 问题解决
3.4.1 已经输入了,但是为什么判断还为空?
这个问题需要使用“延迟变量”解决。
3.4.2 可是没有跳到第6行,而是跳出,直接到了18行?
和上面问题一样,也是用“延迟变量”解决。
延迟变量是什么?
举例子,把 set 和下面的 if语句看成两个人干活。
正常情况下,set 干完活 if 就去拿 set 赋值完变量去用。
但是,因为 set 干活慢(执行指令时间长),还没干完,if就去拿结果,if肯定拿不到结果。
if去拿了,set又不能不给,所以给了个错误结果,也许是随机值,也许是不完整的值。
此时巧了,if拿到了空值,所以 if 语句成立,但是刚执行完第10行,set活干完了,
可能把内存中 第12行的内容覆盖了(具体没有去看,先这么认为),然后就出现错误,跳出了 2 层if,继续执行后面第18行当内容
延迟变量的缺点。
如果全文开启,那么在后续使用都要把 % 替换成 ! ,在有些不需要延迟变量的地方,还可能出去其他问题。
所以,最好像下面代码里修改的一样,哪里用到,在哪里开启,用完直接关闭。下次再用到,再打开。
四、问题解决
4.1 使用“延迟变量”
红框处,是增加代码,箭头处把 %adb_PATH% 改成 !adb_PATH!
细心的你肯定发现,18行输出的代码结果还是不对。原因还是没有使用“延迟变量”。
只不过这次干活的人把 if 换成里 echo ,其实最后的结果 执行了第23行就对了。
18行那个输出只是调试用看的,调试完删除即可。
4.2 修改后的代码
@echo offset updata_conf_flag=False@REM 检查adb_PATH变量是否空
:input_adb_PATH
if "%adb_PATH%" == "" (set /p "adb_PATH=[ INPUT ] 请输入adb路径:" setlocal enabledelayedexpansionif "!adb_PATH!" == "" ( echo ----adb_PATH=%adb_PATH%@REM 再次检查是否为空 goto input_adb_PATH) setlocal disabledelayedexpansion@REM bug:上面内容执行了,下面2句内容没有执行,为什么?set updata_conf_flag=Trueecho 1updata_conf_flag1=%updata_conf_flag%
)
echo aldkfjif "%updata_conf_flag%" == "True" (echo updata_conf_flag1=%updata_conf_flag%
) else (echo updata_conf_flag2=%updata_conf_flag%
)@REM
echo. && echo. && echo. && pause
免责声明:本号所涉及内容仅供安全研究与教学使用,如出现其他风险,后果自负。
参考、来源: