【问题标题】:Why can't we use a CALL :label command in the FORFILES script?为什么我们不能在 FORFILES 脚本中使用 CALL :label 命令?
【发布时间】:2020-02-03 12:57:42
【问题描述】:

这段代码的sn-p

forfiles /P %pathname% /M *.log /c "cmd /c echo @file"

会很高兴地列出一堆文件。

我们可以将ECHO 替换为RENAMEMOVE 或许多其他内部命令组合:标签名称的CALL 除外。

例如替换上面的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.

Microsoft 的文档中没有提到这种行为,而且由于替代方案非常合适,因此我没有打算让它发挥作用。

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

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

谢谢。

【问题讨论】:

  • cmd /c 打开cmd 的新实例。所以以下只是一个命令行;没有批处理文件的上下文。您可以改用forfor %%a in ("%pathname%\*.log) do call :listit "%%a"
  • 这是因为您正在使用的调用指令正在另一个 cmd.exe 实例中运行,而不是作为批处理文件 cmd.exe 实例的一部分。
  • @Stephan,谢谢,是的,这就是我所使用的。
  • @Compo 是的,我想知道是否可能不是这种情况,所以我尝试了CALL :listit.bat @file 作为替代方案,推理可行,但是嗯......不,它没有。
  • 没有什么不同,你不能在单独的 cmd.exe 实例中调用带有参数的标签并期望它像那样工作。由于您似乎没有将 forfiles 用于特定的事情,比如合并其 /D 选项,您不妨考虑将 findstr /m "^" "%pathname%\*.log" 作为替代方案。

标签: batch-file cmd forfiles


【解决方案1】:

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

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

但如果您需要forfiles 和标签,这可以通过一个简单的技巧来解决。

  1. 在批处理文件的开头,您需要FOR /F ... goto :%%L 行。
  2. 并且在调用标签时必须将其括起来forfiles ... call %~d0\:<myLabel>:\..\%~pn0
@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

来自 aschipfl 的一个好建议:
为了增加一些稳定性(针对路径/文件名中的空格),您可以将调用目的地括在引号call 0x22%~d0\:listit:\..\%~pn00x22 @file

这是仅在forfiles 中的特殊语法,其中0xHH 是字符0x22=" 的十六进制代码。

【讨论】:

  • 感谢 Jeb 这是一段很棒的脚本
  • 因此,将跳转标签嵌入脚本路径的目的是不改变参数的数量,从而不改变%* 的输出,对吧?我将脚本路径放在(转义)引号之间:0x22%~d0\:listit:\..\%~pn00x22...
  • @aschipfl 你是对的。这种技术不会影响脚本的正常行为,尤其是当它已经使用%1... 并且它是任何函数的通用蹦床。我在 batchLibrary 中大量使用它
  • 越来越好......这是对机舱内正在发生的事情的深刻理解。
  • @jeb 你能提供一个参考吗?我试过了,但它似乎没有跳转到指定的标签。据我了解,它基本上是这样做的cmd /c D:\:mylabel:\..\myscript arg1,对吗?我也试过直接在命令行上运行它,但它不起作用。
猜你喜欢
  • 2017-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 2016-10-29
  • 1970-01-01
相关资源
最近更新 更多