批处理脚本相关问题

时间:2014-03-30 06:08:10

标签: windows batch-file csv

我写过以下脚本,在我的系统上运行得非常好。

@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

但是,如下所示,如果有一些修改,它就不会显示任何信息。

@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

)

它也没有给出任何错误。但是,生成的output.csv文件不包含任何数据。

2 个答案:

答案 0 :(得分:1)

更改

IF NOT ERRORLEVEL 1 (

IF NOT %ERRORLEVEL%==1 (

虽然,我不确定使用IPv6而不是IPv4时,ping回复看起来是一样的。您可能希望进一步调查此问题(例如,是IPv6回复的TTL部分吗?)。例如:

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

答案 1 :(得分:1)

延迟扩展

当cmd解析器到达一个行块的行(括号中的行)时,所有变量读取都将替换为它们在分析时具有的值,执行块中的行之前。如果变量的值在块内部发生变化,则在重新读取值的行中不会看到此更改,因为此读取将替换为更改前变量的值。

因此,在第二个代码中,变量正在更改其值,但在输出文件的最终回显中,由于变量读取的值替换为值更改之前的值,因此不会输出任何数据。在块执行开始之前,变量没有任何值。

如果要维护此类代码,则需要启用延迟扩展,并将变量读取中的sintax更改为需要将读取/值扩展延迟到执行时间。

setlocal enabledelayedexpansion
....
if not errorlevel 1 (
    ....
    echo !a!, !b!, !c!
)

<强>算术

SET J=%J%/1024应为SET /A J=!J!/1024,算术需要SET /A

<强> PING

正如JamesL在他的回答中指出的那样,在IPv6的情况下,没有&#34; TTL =&#34; ping命令输出中的数据。

在ipv4 ping命令中设置errorlevel如果有任何打包丢失。在ping非活动的同一子网机器时,您不会丢失数据包。因此,在ipv4中测试活动机器的最佳方法是测试输出中的TTL=值。

在ipv6中,没有TTL输出,但是现在,ping同一个非活动计算机的机器会导致所有数据包丢失。并且仅在所有数据包丢失时才设置errorlevel。如果任何数据包到达其目标,则不设置errorlevel

因此,对于ipv4,测试TTL=,对于ipv6 test errorlevel

<强> WMIC

虽然这种检索数据的方式是正确的并且可行,但在单个查询中检索所有可能的数据会更有效(正如您在之前的问题中所做的那样)。对computersystem数据的六次调用应该写成一个单独的wmic调用。