Batch Script related issue

一曲冷凌霜 提交于 2020-01-06 08:37:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!