问题
I have written following script which works absolutely fine on my system.
@echo off
setlocal enabledelayedexpansion
FOR /F %%i IN ('wmic /node:%1 computersystem get Name') DO SET A=%%i
FOR /F %%i IN ('wmic /node:%1 computersystem get Domain') DO SET B=%%i
FOR /F %%i IN ('wmic /node:%1 computersystem get UserName') DO SET C=%%i
FOR /F %%i IN ('wmic /node:%1 computersystem get Manufacturer') DO SET D=%%i
FOR /F "delims=" %%i IN ('wmic /node:%1 computersystem get Model') DO SET E=%%i
FOR /F %%i IN ('wmic /node:%1 computersystem get SystemType') DO SET F=%%i
FOR /F %%i IN ('wmic /node:%1 bios get SerialNumber') DO SET G=%%i
FOR /F "delims=|" %%i IN ('wmic /node:%1 os get Name') DO SET H=%%i
FOR /F %%i IN ('wmic /node:%1 os get TotalVisibleMemorySize') DO (SET J=%%i)
SET /a J=%J%/1024
FOR /F "delims=" %%i IN ('wmic /node:%1 cpu get Name') DO SET K=%%i
echo %A%,%B%,%C%,%D%,%E%,%F%,%G%,%H%,%J% MB,%K% >> output.csv
But, with some modifications in it which are shown below, it doesn't display any information.
@echo off
setlocal enabledelayedexpansion
ping -n 1 %1 | find "TTL=" > NUL
IF NOT ERRORLEVEL 1 (
FOR /F %%i IN ('wmic /node:%1 computersystem get Name') DO (SET A=%%i)
FOR /F %%i IN ('wmic /node:%1 computersystem get Domain') DO (SET B=%%i)
FOR /F %%i IN ('wmic /node:%1 computersystem get UserName') DO (SET C=%%i)
FOR /F %%i IN ('wmic /node:%1 computersystem get Manufacturer') DO (SET D=%%i)
FOR /F "delims=" %%i IN ('wmic /node:%1 computersystem get Model') DO (SET E=%%i)
FOR /F %%i IN ('wmic /node:%1 computersystem get SystemType') DO (SET F=%%i)
FOR /F %%i IN ('wmic /node:%1 bios get SerialNumber') DO (SET G=%%i)
FOR /F "delims=|" %%i IN ('wmic /node:%1 os get Name') DO (SET H=%%i)
FOR /F %%i IN ('wmic /node:%1 os get TotalVisibleMemorySize') DO (SET J=%%i)
SET J=%J%/1024
FOR /F "delims=" %%i IN ('wmic /node:%1 cpu get Name') DO (SET K=%%i)
echo %A%,%B%,%C%,%D%,%E%,%F%,%G%,%H%,%J%,%K% >> output.csv
)
It is not giving any error either. But, the generated output.csv
file contains no data.
回答1:
Change
IF NOT ERRORLEVEL 1 (
to
IF NOT %ERRORLEVEL%==1 (
Although, I'm not sure the ping reply looks the same when IPv6 is used instead of IPv4. You may want to investigate this further (e.g., is TTL
part of an IPv6 reply?). For instance:
c:\>ping localhost
Pinging Laptop_Name [::1] with 32 bytes of data:
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Ping statistics for ::1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
回答2:
Delayed expansion
When the cmd parser reaches a line of a block of lines (lines surounded in parenthesis), all variable reads are replaced with the value they have at parse time, before executing the lines in the block. If the value of the variable changes inside the block, this change is not seen in the lines where the value is readed, as this read was replaced with the value of the variable before the change.
So, in your second code, the variables are changing its value, but in the final echo to the output file, as the variable reads where replaced with the value before the value change, no data is output. The variables did not have any value before the start of block execution.
If you want to maintain this style of code, you need to enable delayed expansion, and change the sintax in the variable reads that need its reads / value expansion delayed until execution time.
setlocal enabledelayedexpansion
....
if not errorlevel 1 (
....
echo !a!, !b!, !c!
)
Arithmetic
SET J=%J%/1024
should be SET /A J=!J!/1024
, arithmetic requires SET /A
PING
As JamesL indicates in his answer, in the case of IPv6, there is no "TTL=" data in the output of the ping command.
In ipv4 ping command set errorlevel if any packed is lost. And you will not get packets lost when pinging a non active same subnet machine. So the best way of testing for active machine in ipv4 is to test for TTL=
value in output.
In ipv6, there is not TTL
output, but now, pinging a same subnet non active machine you obtain all packet lost. And the errorlevel is only set if ALL the packets are lost. If any packet reaches its target, errorlevel is not set
So, for ipv4, test TTL=
, for ipv6 test errorlevel
WMIC
While this way of retrieving data is correct and will work, is more efficient to retrieve all possible data in a single query (as you did in your previous questions). The six calls for computersystem
data should be written as a single wmic call.
来源:https://stackoverflow.com/questions/22740864/batch-script-related-issue