gpt4 book ai didi

windows - ERRORLEVEL与%ERRORLEVEL%与感叹号ERRORLEVEL感叹号

转载 作者:可可西里 更新时间:2023-11-01 13:55:39 40 4
gpt4 key购买 nike

我认为我对ERRORLEVEL与%ERRORLEVEL%有基本的了解,但是!ERRORLEVEL!使我感到困惑。

我正在制作一个脚本,该脚本调用可执行文件,然后任务列表以查看其是否正在运行,然后通过taskkill将其杀死,然后尝试输出错误级别并针对其他exe重复此操作,而我意识到我真的不明白批处理中的错误级别。

我将变量设置为!errorlevel!
然后在回显中使用不带引号的变量,并且在设置后出现错误时,变量从一个uint16更改为另一个uint16,例如它引用了真实的变量而不是副本。我要复制。有人可以解释这些家伙之间的区别吗?

更新:
这是我正在处理的代码段。

for %%P in (%executableList%) do (
echo ----------------------------------------------------------------------------------
set exeErrorlevel=0
set running=false

start %%~fP
set exeErrorlevel=!ERRORLEVEL!

rem for debugging purposes
echo %%~nP%%~xP older errorlevel %ERRORLEVEL%
echo %%~nP%%~xP newer errorlevel !ERRORLEVEL!
echo before tasklist running var is : !running!

tasklist /FI "IMAGENAME eq %%~fP" | find /I /N /C "%%~fP" >nul && set running=true

echo after tasklist is running var is: !running!

if !running! equ true (
echo %%~nP%%~xP Program is running
taskkill /F /IM %%~nP%%~xP /T
echo %%~nP%%~xP Program was killed

if !exeErrorlevel! == 0 (
echo %passString% %%~nP%%~xP process was started and killed safely
echo %passString% %%~nP%%~xP process was started and killed safely >>%outputfile%
) else (
echo %failString% %%~nP%%~xP process was killed with errorcode !exeErrorlevel!
echo %failString% %%~nP%%~xP process was killed with errorcode !exeErrorlevel! >>%outputfile%
)
) else (
if !exeErrorlevel! == 0 (
echo %passString% %%~nP%%~xP process exited safely
echo %passString% %%~nP%%~xP process exited safely >>%outputfile%
) else (
taskkill /F /IM %%~nP%%~xP /T
echo %failString% %%~nP%%~xP process abruptly exited with errorcode !exeErrorlevel!
echo %failString% %%~nP%%~xP process abruptly exited with errorcode !exeErrorlevel! >>%outputfile%
)
)

echo. >>%outputfile%


)

我需要确保exeErrorlevel在某个时间点具有错误级别的副本-我只想从exe中捕获错误,而不是从tasklist/find/taskill的成功/失败中捕获错误。我担心由于延迟扩展,exeerrorlevel在执行时正在访问延迟的错误级别。也许应该将其设置为exeErrorlevel =%errorlevel%。在我回显旧变量和新变量的行中通常返回不同的整数吗?在我所有的测试运行中,%errorlevel%似乎通常返回0,而!errorlevel!则返回0。对于具有错误退出代码的可执行文件,始终为非零。

最佳答案

错误级别
errorlevel是动态变量的名称(不是放置在环境块中,而是保存在内存中),该变量存储先前执行的过程/命令的退出代码(如果设置了该值,请读取herehereherehere) 。
if命令允许使用if errorlevel n语法检查errorlevel变量的值是否大于或等于n,而无需批处理解析器检索变量的值。

但是,如果我们将批处理解析器用于变量值,则%errorlevel%只是对存储在变量中的值的引用,即读取操作。与!errorlevel!一样。两者之间的主要区别是,而则根据变量扩展上的rules检索值。

使用if errorlevel或检索变量中的值有很大的不同:

  • 变量读取操作将检查环境块是否包含具有指定名称的变量。
  • if构造函数将不进行此测试。

  • 如果您执行 set errorlevel=10之类的操作,则动态 errorlevel值将不会与 %errorlevel%!errorlevel!一起检索,因为在环境中设置的值将隐藏动态值。但是,由于 if errorlevel不会读取环境块,而是直接读取保存该值的内部变量,因此它可以正常工作。

    变量

    批处理语法不包括以下选项:在内存中具有多个指向同一值的变量,如果其中一个变量更改了其值,则另一个变量将反射(reflect)该更改。

    可以通过在变量扩展中正确使用不同阶段,将变量正确设置为另一个变量的名称并强制批处理解析器对该命令进行两次传递来模拟此行为,以便将第一个变量解析为第二个变量的名称。真正的值(value)。

    你的问题

    简化(甚至无法正常工作)的代码仅用于分析

     1  for %%P in (%executableList%) do (
    2
    3 start %%~fP
    4 set exeErrorlevel=!ERRORLEVEL!
    5
    6 echo %%~nP%%~xP older errorlevel %ERRORLEVEL%
    7 echo %%~nP%%~xP newer errorlevel !ERRORLEVEL!
    8 ....
    9 if !running! equ true (
    10 taskkill /F /IM %%~nP%%~xP /T
    11 if !exeErrorlevel! == 0 (
    12 ....
    13 ) else (
    14 echo process killed with errorcode !exeErrorlevel!
    15 )
    16 ) else (
    17 if !exeErrorlevel! == 0 (
    18 ....
    19 ) else (
    20 taskkill /F /IM %%~nP%%~xP /T
    21 echo process abruptly exited with errorcode !exeErrorlevel!
    22 )
    23 )
  • 第1行:解析do子句中的代码以及所有代码。在开始执行之前,将从代码中删除所有%var%变量读取操作,并替换为变量内部的值。这意味着,如果变量更改了其值,则将无法检索更改的值,因为不存在读取操作,只能获取变量中的初始值。
  • 第3行:在单独的进程中启动可执行文件,而无需等待进程结束。是不是重要?参见下一行
  • 第4行:检索errorlevel变量的当前值(使用的延迟扩展),并将其存储在exeErrorlevel变量中。但是存储的值不是可执行文件返回的errorlevel(单独的过程,不等待其结束,我们如何知道exit code = errorlevel是什么?),而是start命令的退出代码。
  • 第6行:由于删除了%errorlevel%读取操作,因此该行将回显errorlevel子句开始执行之前存储在do变量中的值。
  • 第7行:检索errorlevel变量的当前值。在这里,我们可能会遇到问题。如何执行脚本的命名? .bat.cmd之间有区别。成功后,如果这是set文件,则第4行中的errorlevel命令将清除(设置为0).cmd变量,但如果它是errorlevel文件,则不会更改.bat
  • 第11、14、21行:如图所示,exeErrorlevel变量不包含有效值。否,将行更改为!errorlevel!不会检索流程的退出代码,而是taskkill的退出代码。

  • 为了能够检索进程的退出代码/错误级别,我们需要等待它结束。如果您需要启动该进程,如果它继续运行,则将其杀死,然后在两种情况下都检索退出代码,请直接调用该可执行文件或使用 start "" /wait programName,并并行运行该杀死进程(例如 start /b "" monitor.bat programName或类似的程序,然后再启动该程序) )。主进程将等待并检索退出代码。监视进程处理杀死事件。

    关于windows - ERRORLEVEL与%ERRORLEVEL%与感叹号ERRORLEVEL感叹号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42967840/

    40 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com