我有一个批处理脚本,可以产生我想要的最终输出,但是在最终输出之前有两个 "缺少操作数 "的消息。 我在网上梳理了几十条线程,试图找出如何解决防止这些消息的方法,但我还没能找到解决方法......
这是我的脚本。
:Start
cls
@echo off
REM -------------------------------------------------------------------------
REM [ Remotely Verify Max RAM Capacity & Required Stick Sizes & Quantities) ]
REM -------------------------------------------------------------------------
Set /P "Computer=Enter the Computer Name: "
FOR /F "tokens=1,2 skip=1" %%G in ('wmic /node:"%Computer%" memphysical get MaxCapacity^, MemoryDevices') do (set /A "ramcapacity=%%G" & set /A "ramslots=%%H")
set /A "trueram=ramcapacity/1048576"
set /A "sticksizes=ramcapacity/1048576/ramslots"
echo Max RAM = %trueram%GB / %ramslots% sticks @ %sticksizes%GB
Goto End
:End
这是一个输出的例子 And here's an example of the output:
Missing operand.
Missing operand.
Max RAM = 64GB / 4 sticks @ 16GB
既然我能够得到我所期望的输出结果 缺少操作数的消息并不是什么大问题 但我还是想知道为什么会发生这种情况 以及如何防止它们发生(如果可能的话)。
那是因为 wcic
有那个丑陋的句子结尾的 CRCRLF
而不是仅仅 CRLF
. 第一个 CR
成为变量的一部分 %%G
%%H
. 由于计算是正确的,你可以用以下方法抑制错误信息 2>nul
. 要想真正解决这个问题,最安全和最通用的方法是用另一个 for
循环。
@echo off
setlocal
FOR /F "tokens=1,2 skip=1" %%G in ('wmic memphysical get MaxCapacity^, MemoryDevices') do (
for /f %%a in ("%%G") do set "ramcapacity=%%a"
for /f %%a in ("%%H") do set "ramslots=%%a"
)
set /A "trueram=ramcapacity/1048576"
set /A "sticksizes=ramcapacity/1048576/ramslots"
echo Max RAM = %trueram%GB / %ramslots% sticks @ %sticksizes%GB
注意: 你并不真的需要 set /a
之内 for
循环。简单地将一个数字分配给一个变量。set var=12345
即可。使用 set /a
只做运算。
另一种方法是避免在行末使用字符串。在下面的代码中,我添加了(但后来没有使用)第三个标记(Width
- 最后一个 wmic memphysical
作为 wmic
按字母顺序排列),因此,这两个 %%G
和 %%H
不包括 CR
. 我还用 ^|findstr /v "^$"
来跳过空行(这样会用空值覆盖我们的变量)。
@echo off
setlocal
FOR /F "skip=1 tokens=1,2" %%G in ('wmic memphysical get MaxCapacity^, MemoryDevices^,Width ^|findstr /v "^$"') do (
set "ramcapacity=%%G"
set "ramslots=%%H"
)
set /A "trueram=ramcapacity/1048576"
set /A "sticksizes=ramcapacity/1048576/ramslots"
echo Max RAM = %trueram%GB / %ramslots% sticks @ %sticksizes%GB
取而代之的是:
do (set /A "ramcapacity=%%G" & set /A "ramslots=%%H")
简单地写。
do (set /A "ramcapacity=%%G" & set /A "ramslots=%%H") 2> nul
The 2> nul
部分 只是抑制了错误信息。
错误信息的根本原因是由于 wmic
返回Unicode文本,其中 for /F
未能正确地将其转换为ASCIIANSI文本,因为它留下了无用的回车字符。所以,在你的情况下,在有内存信息的那行之后,在你的内存中加入 for /F
再迭代一次,使这样的字符在 %%G
因此,试图通过 set /A "ramcapacity=%%G"
,最后返回错误信息。
为了避免这样的转换假象,可以将另一个 for /F
循环,像这样。
for /F "skip=1 delims=" %%I in ('
wmic /NODE:"%Computer%" MemPhysical get MaxCapacity^,MemoryDevices
') do (
for /F "tokens=1,2" %%G in ("%%I") do (
set /A "ramcapacity=%%G" & set /A "ramslots=%%H"
)
)
一般来说,我建议使用 /VALUE
的选择。wmic
命令,结果如下。
MaxCapacity=67108864 MemoryDevices=4
因为这样可以避免值串被右面的空格所填充 (尽管在你的情况下它们并不干扰,因为你使用的是 set /A
):
set "ramcapacity=" & rem // (ensure this variable is initially undefined)
for /F "delims=" %%I in ('
wmic /NODE:"%Computer%" MemPhysical get MaxCapacity^,MemoryDevices /VALUE
') do (
for /F "tokens=2 delims==" %%J in ("%%I") do (
rem // The condition ensures that the only first line is processed:
if not defined ramcapacity set /A "ramcapacity=%%J"
rem // Here is no condition, so the last (second) line is relevant:
set /A "ramslots=%%J"
)
)
我甚至会更进一步,避免明确定义变量,比如: ramcapacity
和 ramslots
,因为返回的字符串 MaxCapacity=67108864
和 MemoryDevices=4
看起来已经是完美的表情了 set
命令。
for /F "delims=" %%I in ('
wmic /NODE:"%Computer%" MemPhysical get MaxCapacity^,MemoryDevices /VALUE
') do (
for /F "delims=" %%J in ("%%I") do (
rem // This implicitly defines variables `MaxCapacity` and `MemoryDevices`:
set /A "%%J"
)
)
set /A "TrueRAM=MaxCapacity/(1<<20), StickSizes=TrueRAM/MemoryDevices"
echo Max RAM = %TrueRAM% GiB / %MemoryDevices% sticks @ %StickSizes% GiB