批处理脚本中嵌套标签的怪异行为



下面是批处理程序:

@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循环。

我已经读过关于/I选项,据说可以防止goto脱离iff和do循环,但我不完全确定它是如何工作的(我尝试将其添加为参数,但它要么出错,要么似乎不做任何事情)。

任何帮助都将非常感激!

: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。在代码块中不允许使用标签。当if语句为parsed时,%var%的值被替换为当时这些变量的值,而不是由于块内执行的操作而导致的更改。小心延迟膨胀陷阱

以上代码将:while1循环转换为由CALL :while1调用的内部子程序(冒号是所需的,以指示调用是内部标签)

注意GOTO :EOF语句。它们将执行转移到物理结束文件(冒号也是必需的),首先是防止执行通过流式从:run_test继续到:while1。第二个是在:while1例程结束时强制返回CALL :while1后面的语句。:while1例程可以放在批处理主线中的任何goto语句之后。notagotoin a code block)。

最新更新