Batch file 批处理文件中嵌套for循环的正确语法
我试图在许多服务器上查询已安装应用程序的注册表值。我可以硬编码的服务器,并有很多重复,它似乎工作。但有时服务器列表可能会改变,我想采用更合理的模块化方法 因此,我可以提供一个带有服务器名称列表的测试文件,然后查询所有这些服务器的注册表值,并将它们输出到日志文件中 我认为问题肯定出在我的循环/变量存储上。不确定到底发生了什么,但似乎一旦我得到一组注册表值,就会为每个服务器输出这些值,而不管它们各自的注册表值如何 我对这种脚本编写没有太多的经验,所以我一直在尝试和错误地将它们混合在一起,下面是我到目前为止所做的。请指出我犯过的任何糟糕的语法错误 因此,本质上这是为了找到安装在每台服务器上的McAfee扫描引擎版本。McAfee控制台本身的报告并不总是可靠的,我想检查内容是否已成功下载到每台服务器 创建完整引擎版本需要两个注册表值,因此我需要将这两个值都提取出来,然后将它们组合成一个字符串 目前,我确实得到了一个看起来正确的输出,但它并不代表实际安装到每个服务器上的内容。这就像一个值被提取然后被复制 另外,这似乎只有在命令行中执行时才起作用。在运行它的前1-2次时,不会提取任何值。感觉我离解决问题的办法还很远Batch file 批处理文件中嵌套for循环的正确语法,batch-file,cmd,registry,Batch File,Cmd,Registry,我试图在许多服务器上查询已安装应用程序的注册表值。我可以硬编码的服务器,并有很多重复,它似乎工作。但有时服务器列表可能会改变,我想采用更合理的模块化方法 因此,我可以提供一个带有服务器名称列表的测试文件,然后查询所有这些服务器的注册表值,并将它们输出到日志文件中 我认为问题肯定出在我的循环/变量存储上。不确定到底发生了什么,但似乎一旦我得到一组注册表值,就会为每个服务器输出这些值,而不管它们各自的注册表值如何 我对这种脚本编写没有太多的经验,所以我一直在尝试和错误地将它们混合在一起,下面是我到目
SET LOGFILE=C:\LogFile.log
For /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query \\%%i\HKLM\SOFTWARE\McAfee\AVEngine /v EngineVersion32Major ^| find /i "EngineVersion32Major"') do set /a major=%%a
for /f "tokens=3" %%b in ('reg query \\%%i\HKLM\SOFTWARE\McAfee\AVEngine /v EngineVersion32Minor ^| find /i "EngineVersion32Minor"') do set /a minor=%%b
echo %%i: %major%.%minor% >> %LOGFILE%
)
预期的输出如下所示:
server1 : 5900.5647
server2 : 6000.4589
server3 : 5900.5647
server4 : 5900.5647
为您能提供的任何帮助干杯。语法与
无关,但与cmd
如何解析脚本无关。看
当cmd
解析块(parens中的任何内容)时,将其作为一行进行处理。因此,它将任何%var%
扩展到其实际内容。在退出块之前,不会考虑对其所做的更改。要检索块中的新内容,必须启用延迟扩展
,这将强制解析器在每次迭代中对其进行评估。此外,语法必须从%var%
更改为!瓦尔代码>
在这里,还从set
命令中删除了/a
开关,因为您没有进行计算,您可能会得到意想不到的结果(假设一个小版本等于0080
,它将被视为八进制(无效)并会破坏脚本)。另外,请注意用引号括起来的var名称和var内容(set“minor=%%b”
),以避免不需要的尾随/前导空格
此外,我认为您不需要^ | find/I“EngineVersion32Major
部分,因为名为EngineVersion32Major
的键可能只包含您正在查找的内容。此外,请将数据括在引号中(永远不知道何时会出现空格)。您还可以通过“skip=1 tokens=3”更改“
避免处理标题reg
回波
因此
此外,无论是否启用延迟扩展(请注意双百分号),这都在块内工作
另一个问题是,无论何时在块中使用重定向,系统都会打开和关闭文件(或流)
但是
处理块中的所有命令,因此文件只打开和关闭一次。这可能会提高性能,特别是对于大文件
顺便说一句
与
(
...
...
)>>"%LOGFILE%"
它与for
语法无关,而是与cmd
如何解析脚本有关。看
当cmd
解析块(parens中的任何内容)时,将其作为一行进行处理。因此,它将任何%var%
扩展到其实际内容。在退出块之前,不会考虑对其所做的更改。要检索块中的新内容,必须启用延迟扩展
,这将强制解析器在每次迭代中对其进行评估。此外,语法必须从%var%
更改为!瓦尔代码>
在这里,还从set
命令中删除了/a
开关,因为您没有进行计算,您可能会得到意想不到的结果(假设一个小版本等于0080
,它将被视为八进制(无效)并会破坏脚本)。另外,请注意用引号括起来的var名称和var内容(set“minor=%%b”
),以避免不需要的尾随/前导空格
此外,我认为您不需要^ | find/I“EngineVersion32Major
部分,因为名为EngineVersion32Major
的键可能只包含您正在查找的内容。此外,请将数据括在引号中(永远不知道何时会出现空格)。您还可以通过“skip=1 tokens=3”更改“
避免处理标题reg
回波
因此
此外,无论是否启用延迟扩展(请注意双百分号),这都在块内工作
另一个问题是,无论何时在块中使用重定向,系统都会打开和关闭文件(或流)
但是
处理块中的所有命令,因此文件只打开和关闭一次。这可能会提高性能,特别是对于大文件
顺便说一句
与
(
...
...
)>>"%LOGFILE%"
请使用搜索
功能查找有关延迟扩展
的许多SO文章
在您的案例中,最简单的方法是使用
call echo %%i: %%major%%.%%minor%% >> %LOGFILE%
请使用搜索
功能查找有关延迟扩展
的许多SO文章
在您的案例中,最简单的方法是使用
call echo %%i: %%major%%.%%minor%% >> %LOGFILE%
明亮的谢谢你讲了这么多细节。正如我所说,我对这方面比较陌生,只是把不同的东西混合在一起。干杯,太棒了!谢谢你讲了这么多细节。正如我所说,我是
(
...
...
)>>"%LOGFILE%"
call echo %%i: %%major%%.%%minor%% >> %LOGFILE%