如何修复管道延迟扩展条件的批处理脚本错误?

时间:2015-10-08 19:08:36

标签: windows batch-file cmd

我制作了一个CMD批处理脚本,供Windows 7使用。

我必须使用管道条件。

但是这个我的批处理脚本没有像我预期的那样工作。

为什么在管道中的脚本下面不起作用?

低于echo |语法是必须要管道的虚拟条件。

不平衡报价是必需条件。

我必须在不使用SETLOCAL ENABLEDELAYEDEXPANSION的情况下完成。

我必须只使用cmd.exe /v:on /c " .... "

@echo off
echo | cmd.exe /v:on /c "set z=Car and" Airplane is Machine & echo !z!"

rem OR

echo | cmd.exe /v:on /c "set z=Car and" Airplane is Machine & call echo %%z%%"

pause >nul
exit 0

结果是:

!z!"
"

为什么不使用管道操作符同时处理两个批处理命令行?

编辑 - dbenham的解释:

荒谬的命令只是一个基本的测试平台,可以证明OP所遇到的问题。

OP希望管道的右侧是CMD.EXE进程,该进程定义包含奇数引号的变量,然后回显结果值。问题写得不好,但这是一个有趣的问题。我留下了原来的问题,以防我的解释不正确。

2 个答案:

答案 0 :(得分:1)

这听起来像家庭作业。或者是一个谜语。

假设最后一个(首先是关闭主题):

echo Car and^" Airplane is Machine|cmd /v:on /c "set /p z=&echo !z:is=are!s"

应符合要求:

echo | syntax is a must. 检查

unbalance quote is required. 检查

no usage of SETLOCAL ENABLEDELAYEDEXPANSION. 检查

use cmd.exe /v:on /c " .... ". 检查

结果是:

Car and" Airplane are Machines

(替换以证明它显示第二个echo,而不是第一个

答案 1 :(得分:1)

您的问题与管道无关。您的问题是如何正确地转义命令字符串,使得赋值在值中包含奇数个引号,然后您的ECHO命令正确显示结果值。如果删除管道并且只是单独执行CMD.EXE命令,则会遇到完全相同的问题。

在我提供解决方案之前,你绝对应该看看Why does delayed expansion fail when inside a piped block of code?深入探索复杂管道操作的复杂性。

有一些事情会使您的问题复杂化:

1)命令字符串被多次解析 - 首先是主批处理脚本,在这种情况下,您必须确保&被引用或转义,以便将其传递给CMD.EXE。第二次由CMD.EXE本身解析,这次你需要以某种方式在赋值中包含引号,但现在&不能被转义或引用,以便它正确触发ECHO命令来显示结果。

2)在执行之前,CMD.EXE将删除包含命令字符串的最外面的引号。但是知道外部引号不是必需的是有帮助的:-)你只需要找到正确的转义和引用序列。

有许多解决方案,而且完全可以预测。然而,当试图追踪它的工作方式时,它很容易让你的头爆炸; - )

以下所有工作。我在输出周围添加了方括号,以证明赋值中不包含不需要的字符。不需要的IGNORED文本只是为了演示引用的赋值如何忽略最后一个引用之后的文本。可以简单地删除IGNORED文本。

@echo off

:: Without quotes around the command
echo | cmd.exe /v:on /c set z=Car^^" and Airplane is Machine&echo [!z!]
echo | cmd.exe /v:on /c set z=Car^^^" and Airplane is Machine^&echo [!z!]


:: With quotes around the command
echo | cmd.exe /v:on /c "set z=Car^" and Airplane is Machine^&echo [!z!]"
echo | cmd.exe /v:on /c ^"set z=Car^^" and Airplane is Machine&echo [!z!]"


:: With quotes around the assignment such that text after the last quote is ignored
:: Without quotes around the command
echo | cmd.exe /v:on /c set "z=Car" and Airplane is Machine^^" IGNORED & echo [!z!]
echo | cmd.exe /v:on /c set ^^"z=Car" and Airplane is Machine" IGNORED & echo [!z!]
echo | cmd.exe /v:on /c set "z=Car" and Airplane is Machine^^^" IGNORED ^& echo [!z!]
echo | cmd.exe /v:on /c set ^^"z=Car" and Airplane is Machine^" IGNORED ^& echo [!z!]

:: With quotes around the assignment such that text after the last quote is ignored
:: With quotes around the command
echo | cmd.exe /v:on /c "set "z=Car" and Airplane is Machine^" IGNORED ^& echo [!z!]"
echo | cmd.exe /v:on /c "set ^"z=Car" and Airplane is Machine" IGNORED ^& echo [!z!]"
echo | cmd.exe /v:on /c "set "z=Car^" and Airplane is Machine^^" IGNORED & echo [!z!]"
echo | cmd.exe /v:on /c "set ^"z=Car^" and Airplane is Machine" IGNORED & echo [!z!]"

- RESULT -

[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]
[Car" and Airplane is Machine]

当然,您的实际代码明显不同。如果您在尝试将这些概念应用于实际问题时还有其他工作要做,我不会感到惊讶。祝你好运!