命令行 Windows:如何在调用中设置全局变量?

命令行 Windows:如何在调用中设置全局变量?

我想改变调用函数内的计数器变量。

在我的例子中,我想要计算所有子文件夹 (= count_all) 然后我想要增加成功进行的子文件夹的数量 (= count_done)。

    @echo off
    cls

    setlocal enableextensions enabledelayedexpansion
    set /a "count_all=0"
    set /a "count_done=0"

    for /d /r %%i in (.\*) do call :process_subfolders "%%i"

    if %count_all% EQU 0 (
        echo No archives found.
    ) else (
        set /a "counted=1"
        for /d /r %%i in (.\*) do call :process_subfolders "%%i"
    )

    pause
    endlocal
    goto :eof

    ::___________________________________________________________________
    :process_subfolders
    set "folder=%~nx1"

    pushd %folder%
    if exist *.rar (
        if !counted! equ 0 (
            set /a "count_all+=1"
        ) else (
            set /a "count_done+=1"
            echo !count_done!: %folder%

            rem ... do something with the rar files in this folder ...
            rem ... for testing: use ping
            ping 127.0.0.1 -n 2 > nul

            set /a "percent=!count_done!*100/!count_all!"
            title !percent!%% [!count_done!/!count_all!]
        )
    )
    popd
    exit /b

代码可以运行,但我不明白 的行为setlocal enabledelayedexpansion。当我将其放入调用中时,:process_subfolders我无法再更改变量,也不知道如何相应地返回它们。我可以通过某种方式在调用结束时设置它们endlocal & set "%2=whatever"(或类似的东西),但我仍然不明白哪些变量是本地的,哪些不是。

count_all%count_all%和之间有什么区别?!count_all!我应该何时使用哪一个?

答案1

我建议使用 FOR /D 命令

一个小测试示例:

setlocal enabledelayedexpansion
set /a count_all=0
for /d /r %%i in (.\*) do (
  echo !count_all! : %%i
  set /a count_all+=1
)  
echo all: %count_all%

至于各种变量替换运算符之间的区别,您并不是唯一一个感到困惑的人。

主要区别在于替换运算符%或是否!与变量的当前值或初始值相关。

EnableDelayedExpansion 选项 导致变量在执行时扩展,而不是在解析时扩展。延迟扩展生效时,可以使用 立即读取变量!variable_name!。使用%variable_name%将继续显示在行首扩展的初始值,对于循环来说,这可能有所不同。

我在代码中添加了一个echo命令来演示差异。它使用!count_all!,因为使用会导致命令启动%count_all%时的值,即始终为。但不需要运算符,因为它被编程为循环变量。for0%%i!

您可以在以下帖子(获得最多支持的答案)中找到详细的解释:
SETLOCAL 和 ENABLEDELAYEDEXPANSION 如何工作?

这两个代换运算符的不一致导致了混乱,而这并不总是能通过逻辑解决的。有时需要反复试验才能找到正确的答案。

相关内容