Batch file 为什么可以';我们不能在FORFILES脚本中使用CALL:label命令吗?

Batch file 为什么可以';我们不能在FORFILES脚本中使用CALL:label命令吗?,batch-file,cmd,forfiles,Batch File,Cmd,Forfiles,这段代码 forfiles /P %pathname% /M *.log /c "cmd /c echo @file" 会很高兴地列出一堆文件 我们可以用RENAME或MOVE或许多其他内部命令组合来替换ECHO:例外情况是对标签名进行调用 例如,按如下方式更换上面的ECHO: forfiles /P %pathname% /M *.log /c "cmd /c CALL :listit @file" : : : : exit /b :listit echo %1 exit /b 我希

这段代码

forfiles /P %pathname% /M *.log /c "cmd /c echo @file"
会很高兴地列出一堆文件

我们可以用
RENAME
MOVE
或许多其他内部命令组合来替换
ECHO
:例外情况是对标签名进行
调用

例如,按如下方式更换上面的
ECHO

forfiles /P %pathname% /M *.log /c "cmd /c CALL :listit @file"
 : :
 : :
exit /b

:listit
echo %1
exit /b
我希望它会有相同的输出,通常会给出错误消息

Invalid attempt to call batch label outside of batch script.
这种行为并不是微软文档中提到的,而且由于替代方案是完全足够的,所以我没有去寻找它的工作

但是我对井感兴趣,为什么不呢?!,所以我提出了这个问题

为什么不能在FORFILES脚本中使用CALL:label命令?


谢谢。

正如@Stephan已经评论的那样,它不能使用标签,因为它是在命令行上下文中执行的

在大多数情况下,您可以使用更简单的
FOR
命令

但是在需要文件和标签的情况下,这可以通过一个简单的技巧解决

  • 在批处理文件的开头,您需要/F的行
    。。。转到:%%L
  • 当调用标签时,它必须包含在文件中。。。调用%%d0\:\..\%~pn0
  • 来自aschipfl的好建议:
    要增加一些稳定性(针对路径/文件名中的空格),可以将调用目标括在引号中
    call0x22%~d0\:listit:\..\%~pn00x22@file


    这是一种特殊语法,仅适用于
    forfiles
    ,其中
    0xHH
    是字符
    0x22的十六进制代码=“

    cmd/c
    打开
    cmd
    的新实例。因此,下面只是一个命令行;批处理文件没有上下文。您可以改为使用
    for
    for%%a in(“%pathname%\*.log”)do call:listit“%%a“
    这是因为您正在使用的调用指令正在另一个cmd.exe实例中运行,而不是作为批处理文件cmd.exe实例的一部分。谢谢,是的,这就是我使用的。是的,我想知道情况是否不是这样,所以我尝试了一个
    调用:listit.bat@file
    作为替代,推理是可行的,但是嗯。。。不,它没有。这也没什么不同,您不能在单独的cmd.exe实例中调用带有参数的标签,并期望它能像这样工作。由于您没有使用特定的代码> > FixFrase\Cuth>,如结合其<代码> /d>代码>选项,您可能希望考虑<代码> FordSTR/M“^”“%PACTURNE%**.log”作为替代。谢谢这是一个很棒的脚本,因此将跳转标签嵌入脚本路径的目的是不改变参数的数量,从而不改变
    %*
    的输出,对吗?我将脚本路径放在(转义)引号之间:
    0x22%~d0\:listit:\..\\%~pn00x22
    ..@aschipfl您是对的。此技术不会影响脚本的正常行为,尤其是当它已经使用
    %1
    。。。这是一个普通的蹦床对任何功能。我在我的批处理库中大量使用它变得越来越好。。。这是对机舱发生的事情的深刻评价。@jeb你能提供一个参考吗?我试过了,但它似乎没有跳转到指定的标签。据我所知,它基本上是这样做的
    cmd/cd:\:mylabel:\..\myscriptarg1
    ,对吗?我还试着直接在命令行上运行它,但它不起作用。
    @echo off
    FOR /F "tokens=3 delims=:" %%L in ("%~0") DO goto :%%L
    
    ...
    forfiles /P %pathname% /M *.log /c "cmd /c CALL %~d0\:listit:\..\%~pn0 @file"
    ...
    
    :listit
    echo %1
    exit /b