我的批处理脚本用于测量网络可以处理的两台PC之间的流量。因此,脚本确定文件的大小,然后将其从一台PC发送到另一台PC,并计算该文件可以工作多少次。但是,在计算成功传输的字节总数时存在一个怪异的问题。计算后通过asdf3
打印的环境变量echo
的值似乎不准确。
echo hat %count% mal geklappt
echo size: %menge% byte
set /a asdf3=%count%*%menge%
echo es wurden %asdf3% byte verschoben
上面的行产生以下输出:
hat 58 mal geklappt
size: 30245 byte
es wurden 2722050 byte verschoben
如果我的数学没问题,应该为1754210(58 * 30245)。
变量的初始化如下:
set file="test.odt"
FOR /F "usebackq" %%A IN ('%file%') DO set /A menge=%%~zA
set /A count=0
:marker
COPY /Y /V %file% \\%name%\Users\public
if 0==%errorlevel% (
set/Acount=%count%+1
goto :marker
)
为什么对批处理文件中的简单算术表达式求值会产生2722050
而不是预期结果1754210
?
答案 0 :(得分:1)
请勿使用语法set variable="value"
。最好使用语法set "variable=value"
并按原样引用环境变量值,或者将其与固定字符串或双引号中包含的其他环境变量引用串联在一起。还请查看关于Why is no string output with 'echo %var%' after using 'set var = text' on command line?的答案,它甚至更详细地说明了为什么最好使用set "variable=value"
并在变量名的第一个"
之前使用for /F
。
请勿使用专为逐行处理文本文件,命令行的字符串或捕获的输出而设计的set /A
来获取文件的属性。
请勿使用%errorlevel%
,这会导致将行的其余部分解释为算术表达式,从而仅定义环境变量,该变量始终在内存中为string类型值。
只要成功复制文件,循环就会无限循环。真的想要吗?
避免将if errorlevel X
与命令 IF 一起使用,因为存在语法X
用于测试先前命令或应用程序的退出代码是否大于或等于{{ 1}}或if not errorlevel X
来测试上一条命令的退出代码是否低于X
,这意味着通常等于0
,因为命令和应用程序不存在负值。
set
和/A
之间缺少空格字符,而/A
和count=%count%+1
之间缺少空格字符。
在命令提示符窗口中运行set /?
时获得的帮助输出为set /A
解释了可以在算术表达式中使用其名称而不用%
或{引用环境变量{1}},只要环境变量名称不包含算术运算符,定界符(例如空格或逗号)且不会错误地解释为整数即可。
Windows命令处理器使用32位有符号整数算术,因此值范围为-2147483648至+2147483647。这意味着结合文件大小,在算术表达式的求值发生未处理或报告的溢出之前,值范围限制为2 GiB,几乎总是导致意外结果。有关更多详细信息,请参见:weird results with IF
除了特殊标签!
之外,无需在 GOTO 命令行上指定以冒号开头的标签。有关详细信息,请参见Where does GOTO :EOF return to?
这是您的代码,无需其他代码即可重写,以解决32位带符号整数限制。
:EOF
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
set "name=127.0.0.1"
set "file=test.odt"
for %%A in ("%file%") do set "menge=%%~zA"
set "count=0"
:marker
if %count% == 100 goto Output
COPY /Y /V "%file%" "\\%name%\Users\public"
if not errorlevel 1 set /A "count+=1" & goto marker
:Output
echo hat %count% mal geklappt
echo size: %menge% bytes
set /A asdf3=count * menge
echo es wurden %asdf3% bytes verschoben
copy /?
echo /?
for /?
goto /?
if /?
有关运算符set /?
的说明,另请参见Single line with multiple commands using Windows batch file。