首页 > 解决方案 > 无法找出导致此批处理脚本错误的原因

问题描述

我有以下批处理文件

@echo off
setlocal enableextensions enabledelayedexpansion

rem // Read all lines from this batch file that begin with `php72 ` and iterate over them:
for /F "delims=" %%C in ('
    findstr /BIC:"php72 " "%~f0"
') do (
    rem // Execute the currently iterated `php72` command line:
    start %%C

    SET checktasklist=true
    FOR /L %%A IN (1,1,30) DO (
        FOR /F %%x IN ('IF "!checktasklist!" == "true" tasklist /NH /FI "IMAGENAME eq php72.exe"') DO (
            IF "%%x" == "php72.exe" (
                timeout /T 1 /NOBREAK >NUL
            ) ELSE (
                SET checktasklist=false
            )
        )
    )
    taskkill /IM "php72.exe" /F > nul 2>&1
)
rem // Avoid to fall into the `php72` command lines another time:
exit /B

php72 ../simulation.php --version 0.9.0.4 --hashsimmilar false --thinkahead 0 --detailed 0 --outfile catacombs.outfile.csv --workingdir "C:/xampp/htdocs/rpg_prog/" --customfight 1,2,,,,1,,,1,,0,0,0,Catacombs1
php72 ../simulation.php --version 0.9.0.4 --hashsimmilar false --thinkahead 1 --detailed 0 --outfile catacombs.outfile.csv --workingdir "C:/xampp/htdocs/rpg_prog/" --customfight 1,2,,,,1,,,1,,0,0,0,Catacombs1
php72 ../simulation.php --version 0.9.0.4 --hashsimmilar false --thinkahead 2 --detailed 0 --outfile catacombs.outfile.csv --workingdir "C:/xampp/htdocs/rpg_prog/" --customfight 1,2,,,,1,,,1,,0,0,0,Catacombs1
.... continued with 190 lines of more simmilar lines like the above

我在这个批处理文件中尝试做的是运行每个php72.exe ...命令,等待 30 秒,但前提是它们仍在运行,并且如果它们在 30 秒后仍然运行,则终止它们,然后转到下一php72.exe ...行。

我已经设法实现了这一点,但大多数情况下,一个php72.exe文件将在大约 0.8 秒内运行,但我仍然执行该tasklist /NH...命令 30 次,这会减慢速度。这就是为什么我想在里面放一个局部变量,如果任务在迭代后没有运行,我不必再次重新测试剩余的迭代量。

现在,我收到"true" was unexpected at this time.此错误。我不明白为什么会发生这种情况,或者我怎样才能实现我想要的行为。任何帮助,将不胜感激。

标签: batch-file

解决方案


问题是部分IF "!checktasklist!" == "true":由于它出现在 内for /F,未转义=的符号会转换为空格,因此您需要对它们进行转义,如下所示:

        ...
        FOR /F %%x IN ('IF "!checktasklist!" ^=^= "true" ...') DO (
        ...

您还可以将标志变量的 FALSE 值更改checktasklist为空,然后简单地使用if defined

    ...
    SET "checktasklist=true"
    FOR /L %%A IN (1,1,30) DO (
        FOR /F %%x IN ('if defined checktasklist tasklist /NH /FI "IMAGENAME eq php72.exe"') DO (
            IF "%%x" == "php72.exe" (
                timeout /T 1 /NOBREAK >NUL
            ) ELSE (
                SET "checktasklist="
            )
        )
    )
    ...

基于原始脚本的完全不同的方法:

换线怎么样:

start "" /B %%C

通过这个:

start "" /B cmd /C %%C ^& taskkill /IM "timeout.exe" /F ^> nul 2^>^&1

timeout这应该在完成每个进程后终止进程(-es) php72


推荐阅读