Tri*_*und 5 windows cmd batch-file
我在编写批处理文件时遇到了一个“奇怪的”(对我来说)问题,希望有人能解释为什么这样做了……我有一个批处理文件建立了一个相当复杂的命令行,我希望它在执行之前将其构建的内容回显到屏幕上,以便我可以检查它是否正确构建。我还有其他方法可以做到这一点1,但是由于各种原因,我尝试了某种形式的东西:
for %%a in (echo "") do %%~a complicated-command-line-with-parameters
Run Code Online (Sandbox Code Playgroud)
想法是它将运行该do部分两次:一次%%a设置为echo(将命令显示在控制台上),一次设置为"":期望它实际上将执行该命令(使用%%~a会去除双引号和所有剩下的就是命令本身)。但是,在echo工作时,命令本身未执行。
对于最小复制,请从命令提示符处运行以下命令:
C:\>for %a in (echo "") do %~a dir
C:\>echo dir
dir
C:\> dir
Run Code Online (Sandbox Code Playgroud)
可以看出,它可以echo很好地运行命令,但是似乎前面的空格dir阻止了它的执行。
但是请注意,手动运行带有前导空格的命令是可以的:
C:\> dir
Volume in drive C is OS
Volume Serial Number is A8BD-F861
...
Run Code Online (Sandbox Code Playgroud)
并且,如果以某种方式尝试运行该命令<space>dir,那么它(可能)会抱怨缺少命令:
C:\>" dir"
'" dir"' is not recognized as an internal or external command,
operable program or batch file.
Run Code Online (Sandbox Code Playgroud)
问题:(%~a一个空字符串)和要运行的命令之间的空格似乎导致整行被忽略... 有人知道为什么吗?
注意:无论是从命令提示符(如上)还是从.BAT文件中运行(更改%a为%%a等等)都没有区别。无论要运行的命令是内置命令(例如dir上述命令)还是独立程序,都没有任何区别。
%~a我发现的“修复”是导致问题的命令之间和命令之间的空间的进一步证据:
C:\>for %a in ("echo " "") do %~adir
C:\>echo dir
dir
C:\>dir
Volume in drive C is OS
Volume Serial Number is A8BD-F861
...
Run Code Online (Sandbox Code Playgroud)
通过"echo "在for命令内部的字符串中添加“分隔空格” ,并将其从do子句(...do %~adir)中删除,该命令可以按我最初的预期工作(尽管我不喜欢在命令前没有空格)。
略过(有点令人生畏)问题的最高答案后,Windows命令解释器(CMD.EXE)如何解析脚本?这SomethingDark有益的联系,更清洁的替代方案,似乎工作:
C:\>for %a in (echo call) do %~a dir
C:\>echo dir
dir
C:\>call dir
Volume in drive C is OS
Volume Serial Number is A8BD-F861
...
Run Code Online (Sandbox Code Playgroud)
在某些情况下,多余的东西call可能会影响某些东西,但目前看来,它似乎可以正常工作。
1我可能已经把@echo on刚刚里面的批处理文件前行,但也引起了提示(例如C:\MyDirectory\SubDir>)中显示,这是我不想。另一个“标准后备”是仅复制行并粘贴echo在第一个副本的前面,但是这样对于他们来说很容易变得不同步!
SomethingDark 已经指出了解释。
这是一行的命令与参数标记的分割。
在您的情况下,命令令牌始终是稍后%~a将被替换的,但即使它为空,解析器也不会重新评估命令令牌。
通过您的修复,dir 命令始终是命令令牌的一部分。
但是当 echo 带有前缀时,它仍然可以回显其余部分。