【问题标题】:Understanding batch for loops with in (%variable1%, %variable2%...)了解带有 in (%variable1%, %variable2%...) 的循环批处理
【发布时间】:2019-01-01 17:16:55
【问题描述】:

我有一些工具正在尝试在 MDT 服务器的后端批处理脚本。这些工具之一是 DISM/ImageX。我试图自动化的是一个检查文件夹的脚本,以便 DISM 可以提取单个 WIM 文件,然后我可以使用另一个实用程序来进行更新。

不进入 WSUS。也不是 SCCM。我知道可以使用它们来完成,但我希望将我的部署时间保持在每个给定操作系统的最新版本接近 15-20 分钟。

我的很多后端工具都可以正常工作,但是我在压缩批处理文件的这一部分时遇到了问题,以便它使用 for 循环来检查目录,而不是重复相同的代码结束了。

我从来没有真正接触过批处理脚本,但是,嘿,它似乎可以完成我能想到的几乎所有技巧,而且我一直在寻找优化我的代码的方法。

也许有人可以看到我在这里尝试用我的批处理文件做什么,告诉我我哪里出错了?

我已经写了很长的路,但我想用 =

setlocal
set EnabledDelayedExpansion
set _d=\\cp
set 3d_=G:\DISM
set 3d7a=%3d_%\7
set 3d7b=%3d_%\7\7.1
set 3d7c=%3d_%\7\7.2
set 3d7d=%3d_%\7\7.3
set 3d7e=%3d_%\7\7.4
set 3d8a=%3d_%\8
set 3d8b=%3d_%\8\8.1
set 3d8c=%3d_%\8\8.2
set 3d8d=%3d_%\8\8.3
set 3d8e=%3d_%\8\8.4
set 3dxa=%3d_%\10
set 3dxb=%3d_%\10\10.1
set 3dxc=%3d_%\10\10.2
set 3dxd=%3d_%\10\10.3
set 3dxe=%3d_%\10\10.4
goto :3d7f

:3d7f
for /f "tokens=5 delims= " %%a in ('%3d7a% %3d7b% %3d7c% %3d7d% %3d7e%') do 
(
if not exist %%a (
mkdir %%a)
goto :3d8f

:3d8f
for /f "tokens=5 delims= " %%a in ('%3d8a% %3d8b% %3d8c% %3d8d% %3d8e%') do 
(
if not exist %%a (
mkdir %%a)
goto :3dxf

:3dxf
for /f "tokens=5 delims= " %%a in ('%3dxa% %3dxb% %3dxc% %3dxd% %3dxe%') do 
(
if not exist %%a (
mkdir %%a)
goto :exit
)

希望创建顶部设置变量中列出的目录,使用迭代 for 循环检查目录是否存在,如果不存在则创建它们。

每个变量步骤都会在另一个全局批处理文件中本地化正确的目标目录,我最终会使用它来分发到其他 MDT 服务器,这是我现在正在处理的部分。

  • 编辑了 Squashman @ 5:34EST 1/1/19 指出的错误(谢谢老兄)

【问题讨论】:

  • 这是什么:&&a?你的意思是这样做:%%a?无论如何,您无需在尝试创建目录之前检查目录是否存在。您可以只创建目录并将错误重定向到 nul 设备。您还缺少每个 FOR 命令的右括号。
  • 是的。是的,谢谢。创建目录并将错误重定向到 nul 设备?没想到...我可以阅读很多编程,但是在编写它时,我的范围相当有限。不过我正在努力,感谢您的更正和提示!
  • 基本上......脚本中没有列出的是“你想为 DISM 使用什么工作站?”因为我使用的工具需要一些硬件/时间来处理,而且我不想使用服务器,因为它有点旧。尝试使用一些 pushd 和 popd 但这不起作用。但你的解释可能会有所帮助。基本上,批处理脚本有很多其他部分都允许通过提升脚本。希望我使用的是域,但此时它都是基于工作组的。但除此之外,由于某些命令非常长,因此变量会缩短很多代码。
  • 请注意pushd 只是设置工作文件夹,它不会推送工作负载(它仍然是运行脚本的服务器)。您需要像 PSEXEC 这样的东西来实际转移工作负载。
  • 而不是 psexec,我正在考虑使用一些 powershell 命令,或者只是 xcopy 文件和工作负载,仍然学习一些如何从脚本来回传输东西,尽管 MDT 正在做大部分工作,我只是把它写成备用脚本以防万一。像 LGPO 之类的

标签: loops batch-file for-loop dism


【解决方案1】:

看起来您可能正在尝试构建类似 IP 地址或类似的结构。用奇怪的变量命名很难分辨。无论如何,这应该让你知道如何去做。这会构建从“0\0\0”到“255\255\255”的文件夹和子文件夹。

 setlocal enableDelayedExpansion
 for /L %%a in (0,1,255) do (
    set a=%%a
    for /L %%b in (0,1,255) do (
        set b=%%b
        for /L %%c in (0,1,255) do (
            set c=%%c
            echo.!a!\!b!\!c!
            mkdir !a!\!b!\!c! >nul 2>&1
        )
    )
 )

如果您的目标使用某种形式的一致结构,那么您应该能够以此为基础来完成它。

【讨论】:

  • 这不是 IP 地址,而是显然是 Windows 版本号。
  • 我知道我可以使用您发布的内容,看看它是如何工作的,谢谢。我只是仍然不确定如何自己编写这个逻辑。我真的不明白如何将变量放入标记/分隔符列表中。也许我在这里使用了错误的工具,但我想做的是使用一个引用在别处设置的变量的列表。如果我从确定我正在访问的服务器的选项列表开始,那么所有子变量都取决于该选择。我正在寻找如何使用具有特定标记的列表,但也许您的建议更容易。
【解决方案2】:

您不需要设置这么多变量(确切地说,根本不需要设置)。
正如 Squashman 已经评论的那样,&&a 应该是 %%a,
你缺少右括号和
无需检查文件夹是否存在(只需将错误消息重定向到 NUL)。
您的 for 循环也是错误的。您不想只使用第五个标记,也不想执行变量列表('the single quotes' 会这样做)。

你只需要简单的for 循环。以下代码具有相同的结果,但更简单、更短:

for %%a in (7 8 10) do (
  for /l %%b in (1,1,4) do (
    ECHO Debug: md "G:\DISM\%%a\%%a.%%b"
    md "G:\DISM\%%a\%%a.%%b" >nul
  )
)

你也可以用for %%b in (1 2 3 4) do (代替for /l

【讨论】:

  • 好吧,变量指向一个全局批处理文件,这个脚本没有显示它,但我将 \\cp 和 G:\ 设置为静态变量,以便我可以改进脚本。不完全确定我需要那么多吗?但变量是 DISM 处理和 imagex 导出到网络文件夹。
猜你喜欢
  • 2014-10-19
  • 1970-01-01
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多