batch-file - 批处理脚本中嵌套标签的奇怪行为
问题描述
这是批处理程序:
@echo off
SETLOCAL EnableDelayedExpansion
set /a incr=0
set arg1=%1
del test_output.csv > NUL 2>&1
del test_output.log > NUL 2>&1
set startTime=%time%
for /d %%i in ("%cd%\*") do call :run_test "%%i"
.\log_parser.exe
type test_output.csv
echo Start Time: %startTime%
echo Finish Time: %time%
exit /B
:run_test
if not "%~nx1" == "shared" (
echo Test: %~nx1
cd %1
del pass_fail_output.csv > NUL 2>&1
echo Running...
cd temp_root_fs
start application.exe
set /a incr=0
:while1
tasklist /fi "IMAGENAME eq application.exe" 2>NUL | find /i /n "application.exe">NUL
if "%ERRORLEVEL%"=="0" (
if %incr% leq 60 (
echo Still running...
timeout /t 1 > NUL 2>&1
set /a incr+= 1
goto :while1
)
echo Test timed out...
taskkill /im application.exe /f
)
echo Test completed...
cd logs
.\pass_fail_parser.exe
type log.log >> ..\..\..\test_output.log
copy pass_fail_output.csv ..\..\
cd ..\..\
)
echo Cleaning...
rmdir /S /Q temp_root_fs
cd ..
)
这是我的预期执行:
- 循环浏览文件夹
- 运行应用程序
- 等待 60 秒,然后在 60 秒后终止应用程序,或者在应用程序完成后继续
- 执行一些其他操作以将日志消息移植到整个日志文件中
第一个循环工作正常,但这是我执行它时当前输出的样子:
Test: test1
Initializing...
Running...
Still running...
Still running...
Still running...
Still running...
Still running...
Still running...
Still running...
Still running...
Still running...
Still running...
Test completed...
1 file(s) copied.
Cleaning...
我知道这不能正常工作,因为我还有 3 个用于测试的文件夹,所以它应该继续到其他文件夹,但不知何故,它似乎很早就脱离了 for 循环。
我已经阅读了据说可以防止 goto 脱离 iff 并执行循环的/I
选项,但我不完全确定它是如何工作的(我尝试将它添加为参数,但它要么出错,要么似乎没有做任何事情) .
任何帮助将不胜感激!
解决方案
:run_test
if not "%~nx1" == "shared" (
echo Test: %~nx1
cd %1
del pass_fail_output.csv > NUL 2>&1
echo Running...
cd temp_root_fs
start application.exe
set /a incr=0
CALL :while1
echo Test completed...
cd logs
.\pass_fail_parser.exe
type log.log >> ..\..\..\test_output.log
copy pass_fail_output.csv ..\..\
cd ..\..\
)
echo Cleaning...
rmdir /S /Q temp_root_fs
cd ..
)
GOTO :EOF
:while1
tasklist /fi "IMAGENAME eq application.exe" 2>NUL | find /i /n "application.exe">NUL
if "%ERRORLEVEL%"=="0" (
if %incr% leq 60 (
echo Still running...
timeout /t 1 > NUL 2>&1
set /a incr+= 1
goto :while1
)
echo Test timed out...
taskkill /im application.exe /f
)
GOTO :EOF
在您的代码中,if not "%~nx1" == "shared" (
最后)
是一个code block
. 代码块中不允许使用标签。%var%
当if
语句被当时那些变量的值替换时,这些值被替换parsed
,而不是由于在块内执行的操作而导致的更改。谨防延迟扩张陷阱
上面的代码将:while1
循环转换为调用的内部子程序(需要CALL :while1
冒号表示调用的是内部标签)
注意GOTO :EOF
语句。这些将执行转移到文件的物理结尾(冒号再次是必需的)首先是为了防止执行从:run_test
进入:while1
通过流过。第二种是在例程完成CALL :while1
时强制返回到后面的语句。:while1
该:while1
例程可以放在批处理主线中的任何 goto
语句之后(即不在goto
代码块内)。
推荐阅读
- python-3.x - 如何使用 Meson 和 Python 依赖项进行交叉编译?
- javascript - 学习 React - ReferenceError
- amazon-web-services - AWS DynamoDB:如何订购 DynamoDB Stream 触发的 Lambda?
- haskell - Haskell 可扩展效果:另一种效果中的效果
- reactjs - 反应条纹 3d 安全
- android - 如何在android中一起使用ffmpeg进行文本和gif叠加
- c - C - 从函数返回浮点值并打印它们
- amazon-cognito - Cognito - 无法为用户添加 cognito:groups
- node.js - Knex.js 忽略了外键约束
- c++ - 通过正则表达式隐藏/折叠/调暗任意代码行(例如隐藏日志记录)