批处理脚本随机无法执行服务停止操作问题排查
问题:批处理脚本停止Wildfly/JBoss服务偶尔无响应,直接跳至删除步骤
我最近碰到一个棘手的小问题——在用来部署EAR文件、启停服务的批处理脚本里,服务状态检测和用户确认提示功能都正常,但偶尔执行停止服务操作时,脚本完全没反应,直接跳过停止步骤跑到删除EAR文件的环节了。
问题代码段
问题集中在检测Wildfly/JBoss服务状态并执行停止的逻辑部分:
for /F "tokens=3 delims=: " %%H in ('sc query %SERVICE_WILDFLY% ^| findstr " STATE"') do ( if /I "%%H" == "RUNNING" ( set /p STOP_WILDFLY="Wildfly 10 Service is running, stop it now? (Y/N) " if /I "%STOP_WILDFLY%" == "Y" ( net stop %SERVICE_WILDFLY% ) ) ) for /F "tokens=3 delims=: " %%G in ('sc query %SERVICE_JBOSS% ^| findstr " STATE"') do ( if /I "%%G" == "RUNNING" ( set /p STOP_JBOSS="JBoss 6.1 Service is running, stop it now? (Y/N) " if /I "%STOP_JBOSS%" == "Y" ( net stop %SERVICE_JBOSS% ) ) )
故障发生时,脚本只会显示用户输入提示,然后直接执行后续的删除操作,完全没有服务停止的反馈;正常执行时则会显示服务停止成功的信息。
问题原因
经过排查,这个问题的根源是Windows批处理的延迟扩展未启用。在for循环中,默认情况下变量会在循环执行前被一次性解析,而不是在循环过程中实时读取变量的最新值。当用户输入Y确认停止服务时,脚本实际上并没有获取到这个刚输入的变量值,导致if判断不成立,直接跳过了net stop命令。
修复后的代码段
通过启用延迟扩展,并将变量引用方式改为!变量!的方式,问题就解决了:
setlocal enabledelayedexpansion for /F "tokens=3 delims=: " %%H in ('sc query %SERVICE_WILDFLY% ^| findstr " STATE"') do ( if /I "%%H" == "RUNNING" ( set /p STOP_WILDFLY="Wildfly 10 Service is running, stop it now? (Y/N) " if /I "!STOP_WILDFLY!" == "Y" ( net stop %SERVICE_WILDFLY% ) ) ) for /F "tokens=3 delims=: " %%G in ('sc query %SERVICE_JBOSS% ^| findstr " STATE"') do ( if /I "%%G" == "RUNNING" ( set /p STOP_JBOSS="JBoss 6.1 Service is running, stop it now? (Y/N) " if /I "!STOP_JBOSS!" == "Y" ( net stop %SERVICE_JBOSS% ) ) ) endlocal
setlocal enabledelayedexpansion:开启延迟扩展,让脚本在执行过程中实时读取变量的最新值!STOP_WILDFLY!、!STOP_JBOSS!:用感叹号引用变量,替代原来的百分号,确保在循环内获取用户输入的实时值endlocal:结束局部环境,避免影响脚本其他部分的变量
内容的提问来源于stack exchange,提问作者Nathan24
相关产品推荐
相关产品推荐

