batch-file - 为什么在运行时将空格插入此批处理文件?

标签 batch-file cmd

我有这个简单的测试脚本:

echo start
falsey ^
&& echo nope
echo end
falsey是我用来帮助测试的微型C程序,它只是返回1:
int main(int argc, const char** argv) {
        return 1;
}

问题是,当我打开cmd并运行此批处理脚本时,它在两个&之间插入了几个空格,这自然会导致它错误地回显nope:
C:\jenkins-foo-test>foo.bat
C:\jenkins-foo-test>echo start
start
C:\jenkins-foo-test>falsey &  & echo nope
nope
C:\jenkins-foo-test>echo end
end

我已经找到了一些解决方法,例如将引号放在&&周围:
falsey ^
"&&" echo nope

在这种情况下,引号实际上不起作用,请参阅@dbenham's answer以了解原因。

删除^并合并两行:
falsey && echo nope

或在&&前面添加一个空格:
falsey ^
 && echo nope

这三个选项中的每一个都不会正确显示nope。但是,当cmd.exe打印正在运行的命令时,它们仍然仍有多余的空间。

那么,为什么要插入这些多余的空格?我如何才能停止cmd.exe破坏事物而不必始终将我的代码扭曲为轻度不自然的形状?

最佳答案

The line continuation ^ escapes the first character on the next line,因此第一个&被视为文字,并作为参数传递给falsey。第二个&被视为简单命令串联。

&&视为条件命令串联的一种简单解决方案是将&&放在前面的行上:

falsey &&^
echo nope

或者您可以在&&之前放置一个空格
falsey ^
 && echo nope

另一种选择是使用jeb在其链接的答案中指出的重定向技巧,但我从不使用该技巧。

关于您的带有引号"&&"的“解决方案”-您在自欺欺人。当falsey失败时,它似乎可以工作。但是,如果您的命令成功执行,那么您将遇到麻烦:
echo ONE ^
"&&" echo TWO

- 输出 -
C:\test>echo ONE "  && " echo TWO
ONE "
'" echo TWO' is not recognized as an internal or external command,
operable program or batch file.

请注意,&&起作用是因为第一个"被转义了,因此&&不加引号。如果在"&&"之前添加空格
echo ONE^
 "&&" echo TWO

那么你得到以下
C:\test>echo ONE "&&" echo TWO
ONE "&&" echo TWO

因为现在空格已转义,并且"&&"被引用了。

关于您的评论,您可以忽略这些多余的空格-它们是在ECHO为ON时解析器如何显示行的构件。解析器通常会大大地重新排列行,但通常不会影响结果。

例如
   <    nul  set test=OK
echo [%test%]

- 输出 -
C:\test>set test=OK 0<nul

C:\test>echo [OK]
[OK]

注意回声的SET线是如何完全重新排列的。重定向将被压缩并移动到语句的末尾,并在重定向之前留一个空格。您可能会认为该空间将包含在分配中,但是您可以看到它不是:-)

您唯一需要担心的是重新安排是否在管道中使用了该命令。

例如:
(set test=OK&call echo [%%^^test%%])|findstr "^"

- 输出 -
C:\test>(set test=OK  & call echo [%^test%] )  | findstr "^"
[OK ]

您会看到SET值中包含一个多余的多余空间。这是实现管道的一种方法-在新的CMD.EXE进程中执行每一边,并且该行被多次解析。您可以使用%CMDCMDLINE%显示传递给左侧cmd.exe的命令行来查看空间的出处。
(set test=OK&call echo [%%^^test%%] %%^^cmdcmdline%%)|findstr "^"

- 输出 -
C:\test>(set test=OK  & call echo [%^test%] %^cmdcmdline% )  | findstr "^"
[OK ] C:\WINDOWS\system32\cmd.exe  /S /D /c" ( set test=OK & call echo [%^test%] %^cmdcmdline% )"

有关许多带有管道的怪癖的更多信息,请参见Why does delayed expansion fail when inside a piped block of code?。特别是,请注意选择的答案,以更好地说明正在发生的事情。

关于batch-file - 为什么在运行时将空格插入此批处理文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37868432/

相关文章:

windows - 简单的 Windows 批处理移动文件夹

使用 CMD/C 暂停时,Powershell ISE 中断

php - 如何在共享驱动器上执行 xpdf (pdftotext.exe)?

batch-file - 如何从批处理文件中提取错误描述

batch-file - 批处理文件变量范围问题

windows - 如何使用批处理文件捕获 Windows 硬件配置?

windows - 带括号和管道的多行 Windows shell 命令

batch-file - 是否有命令检查是否安装了防病毒软件?

windows - 将 jpg 文件递归搜索、复制和重命名为父文件夹名称

java - 如何运行服务器的批处理文件(永久运行)并将控制权返回给java程序而不关闭该批处理