variables与常量的batch file比较失败

我想写一个简单的代码来获得一些很好的“时间戳”。 获取时间到我的两个variablesStartEnd工作正常。 我也可以打印它为0:0:0。 我想要一个前导零,如果它less于10,但显然我得到一个错误,说'参数10没有find或misstyped'。 我发现这似乎是要比较的variables,但我没有解决这个问题。 有任何想法吗?

 @ECHO OFF REM Time Calculation FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO ( set Day=%%A set Hour=%%B set Minute=%%C set Second=%%D ) set /a Start=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100 @ECHO ON ping 8.8.8.8 -n 11 @ECHO OFF FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO ( set Day=%%A set Hour=%%B set Minute=%%C set Second=%%D ) set /a End=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100 set /a Diff=%End%-%Start% set /a Diff=(%Diff%)/100 set /a DiffSec=%Diff%%%60 set /a Diff=(%Diff%-%Diff%%%60)/60 set /a DiffMin=%Diff%%%60 set /a Diff=(%Diff%-%Diff%%%60)/60 set /a DiffHrs=%Diff% ECHO Laufzeit Auftraege loeschen: %DiffHrs%:%DiffMin%:%DiffSec% :: format with leading zeroes if %DiffSec% LSS 10 (ECHO "LESS 10")else %DiffSec% LSS 1 (ECHO "LESS 1") ::if %DiffSec% LSS 10 (set DiffSec=0%DiffSec%)else [%DiffSec%] LSS 1 (set DiffSec=00) ::if %DiffMin% LSS 10 (set DiffMin=0%DiffMin%)else [%DiffMin%] LSS 1 (set DiffMin=00) ::if %DiffHrs% LSS 10 (set DiffHrs=0%DiffHrs%)else [%DiffHrs%] LSS 1 (set DiffHrs=00) ECHO Laufzeit Auftraege loeschen: %DiffHrs%:%DiffMin%:%DiffSec% 

1.debuggingbatch file

要debuggingbatch file以在代码中查找语法错误,build议在将每个echo off修改为echo ON ,从batch file中删除或用命令REM注释掉之后,从命令提示符窗口中运行batch file。

默认情况下,在parsing和预处理之后,Windows命令解释器会输出每个命令行或整个命令块(以及以匹配结束) ,其中,使用%variable% (立即扩展)引用的环境variables已经被环境variables的当前值执行命令行/块。

在batch file顶部@echo off ,该默认行为将被closures,从而在命令行开始时@也会禁用第一个命令行的输出。 batch file的开发完成并且batch file正常工作时,这当然是可喜的。 但是,为了debuggingbatch file不能按预期的方式工作,最好还是通过命令解释程序真正执行命令行来查找batch file执行由于错误而意外退出的位置。

ECHO行为在帮助输出运行echo /?非常简要的解释echo /? 从命令提示符窗口中。

打开命令提示符窗口将导致使用选项/K隐式启动cmd.exe以便在batch file或应用程序执行完成后保持命令进程运行并打开控制台窗口。

batch file包含不带参数/B的命令exit时是个例外,因为在这种情况下,当前命令进程始终独立于调用层次而退出。 exit /B是相同的goto :EOF ,应该使用,而不是只是exit除非有一个真正的理由使用只是exitexit /Bgoto :EOF需要在Windows上默认启用这两个命令扩展。

双击batch file导致启动cmd.exe选项/C closures命令进程及其控制台窗口自动执行应用程序或batch file完成独立于batch file的执行终止的原因。 自动closures控制台窗口的这种行为不适合debuggingbatch file,因为由于语法错误而导致batch file执行终止时无法看到错误消息。

有关Windows命令解释程序选项的更多详细信息,请在命令提示符窗口中运行以下命令: cmd /?

如何使用goto :EOF (冒号在这里是非常重要的exception方式)或者exit /B (只是goto :EOF一个内部别名)来有意解释batch file的执行,这是通过运行goto /?exit /? 在命令提示符窗口中。

为了debugging更大的batch file,在batch file的顶部使用暂时添加的goto来跳转到特定的块并跳转到goto :EOF可以在块debugging后退出批处理。

顺便说一句::是一个无效标签,经常用于batch file中的注释,因为标签行从不显示在batch file的执行中。 但是,在FOR循环的命令块中,不能使用标签,因为Windows命令解释器无法正确解释命令块中带有标签的FOR循环。 由于这个原因,最好使用命令REM (备注)作为注释,因为这个命令是为batch file中的注释而devise的,而且真正可以在batch file中的任何地方使用。

2.batch file错误

使用@ECHO OFF运行@ECHO OFF文件时,通过在命令提示符窗口中使用rem @echo off (在文本编辑器中运行replace)replace注释,可以很容易地看到错误发生在哪一行:

 if %DiffSec% LSS 10 (ECHO "LESS 10")else %DiffSec% LSS 1 (ECHO "LESS 1") 

如果环境variablesDiffSec当前值不低于10ELSE分支由Windows命令解释器执行,该命令解释器以数字10开头。

Windows命令解释程序无法在当前目录中find具有该名称的应用程序,也不能在环境variablesPATHEXT以分号分隔的文件扩展名列表中指定了文件扩展名的环境variablesPATH以分号隔开的目录列表中指定的任何目录中find该应用程序。

错误在这里显然是下一个比较中缺less的IF命令。 所以正确的代码将是

 if %DiffSec% LSS 10 (ECHO "LESS 10") else if %DiffSec% LSS 1 ECHO "LESS 1" 

在多行上编写条件时,这会更容易阅读:

 if %DiffSec% LSS 10 ( ECHO "LESS 10" ) else if %DiffSec% LSS 1 ( ECHO "LESS 1" ) 

语法现在是正确的。

但是第二个条件没有任何意义,因为JosefZ在他的评论中已经提到了。 如果DiffSec值为10或更大,导致执行ELSE分支中的IF命令,则这种情况肯定也不会成立。 所以更多的感觉会使:

 if %DiffSec% LSS 1 (ECHO LESS 1) else if %DiffSec% LSS 10 ECHO LESS 10 

或者,

 if %DiffSec% LSS 1 ( ECHO LESS 1 ) else if %DiffSec% LSS 10 ( ECHO LESS 10 ) 

有关batch file中有效的IF ELSE条件的更多信息,请参阅上面的答案

  • batch file中如果ELSE语法错误?
  • 批处理脚本 – 如果存在使用adb的./sdcard/file.any

3.为数字<10添加前导零

环境variables始终是stringtypes。 对于算术expression式,环境variables的string值在可能的情况下转换为有符号的32位整数,并将算术expression式的结果从带符号的32位整数转换回string。

还有一个IF条件,例如if %DiffSec% LSS 10在执行之前展开,例如, if 5 LSS 10导致从string转换5 (0x35)为整数, 10 (0x31 0x30)也从string转换为整数,整数。

所以如果可能的话,避免这样的数字比较会更快一些。

将一个前导零添加到一个低于10的数字是很容易的,而没有通过使用stringreplace来真正testing数值。

首先,环境variables的当前值被预置为一个(对于两位数字)或更多0 (对于3,4或甚至更多数字)。

 set "DiffSec=0%DiffSec%" 

接下来,从环境variables的当前值向环境variables分配最后的 X个字符,如2的两位数字。

 set "DiffSec=%DiffSec:~-2%" 

stringreplace在SET命令的帮助下解释,通过在命令提示符窗口中运行set /?

这两行的结果是DiffSec的值为099 ,这两行总是两个数字,范围在0099

4.parsing算术expression式

一个算术expression式是set /a之后的string,由Windows命令解释器解释完全不同于其他string。

空格和制表符是单词分隔符,但没有其他特殊含义。 因此,build议使用空格来使算术expression式更易读。

那么有很多操作员在列出的命令SET帮助下显示在运行命令提示符窗口中set /?

进一步的十进制,八进制和hex整数在算术expression式中被解释为整数。

最后,每隔一个string被解释为当前值从string转换为整数的环境variables的名称。

因此,在算术expression式中使用立即或延时扩展是不可取的。

在执行第一个命令之前,在环境variables的当前值replace已经parsing整个命令块的variables引用的命令块中使用时,在算术expression式中引用具有%variable%的环境variables的值是不好的。

使用!variable!引用环境variables的!variable! 在算术expression式中也是不好的,因为它需要启用延迟扩展,导致处理string中的感叹号不再是字面字符。

所以最好总是简单地写variables名称在算术expression式中,如果由于variables名称不包含百分号或感叹号而不能包含空格字符,并且以不能被Windows解释为整数字符的字符开始命令解释器。

在命令行上使用'set var = text'后 , 为什么在'echo%var%'时没有输出string呢? 有关如何使用setset /P (提示符)或set /A (算术expression式)将值分配给环境variables的详细信息。

5.修复和优化代码

有问题的代码可以修复和优化到这个代码:

 @echo off rem Time Calculation for /F "skip=1 tokens=1-4" %%A in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_LocalTime GET Day^,Hour^,Minute^,Second') do ( set Day=%%A set Hour=%%B set Minute=%%C set Second=%%D ) set /A TimeStart=Day * 86400 + Hour * 3600 + Minute *60 + Second @echo on %SystemRoot%\System32\ping.exe 8.8.8.8 -n 11 @echo off for /F "skip=1 tokens=1-4" %%A in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_LocalTime GET Day^,Hour^,Minute^,Second') do ( set Day=%%A set Hour=%%B set Minute=%%C set Second=%%D ) set /A TimeEnd=Day * 86400 + Hour * 3600 + Minute *60 + Second set /A TimeDiff=TimeEnd - TimeStart set /A DiffSec=TimeDiff %% 60 set /A TimeDiff=(TimeDiff - DiffSec) / 60 set /A DiffMin= TimeDiff %% 60 set /A DiffHrs=(TimeDiff - DiffMin) / 60 set "DiffSec=0%DiffSec%" set "DiffSec=%DiffSec:~-2%" set "DiffMin=0%DiffMin%" set "DiffMin=%DiffMin:~-2%" set "DiffHrs=0%DiffHrs%" set "DiffHrs=%DiffHrs:~-2%" echo Time needed for orders deletion: %DiffHrs%:%DiffMin%:%DiffSec% 

为了理解使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • echo /?
  • for /?
  • ping /?
  • rem /?
  • set /?
  • wmic /?
  • wmic path /?
 if %DiffSec% LSS 10 (ECHO "LESS 10")else IF %DiffSec% LSS 1 (ECHO "LESS 1") 

你需要一个ifelse