导致意外行为的批处理回显管道符号

Posted

技术标签:

【中文标题】导致意外行为的批处理回显管道符号【英文标题】:batch echo pipe symbol causing unexpected behaviour 【发布时间】:2009-12-06 10:31:08 【问题描述】:

我的批处理文件中有一个变量,它包含管道符号(这个:|),所以当我回显该变量时,我收到有关无法识别的内部/外部命令的错误。

我需要一种方法让它正确地回显它,或者更好地删除所有内容,包括 |符号以及它之前的任何额外空格。

【问题讨论】:

【参考方案1】:

在 Windows 批处理文件中使用时,通常必须转义几个特殊字符。这是部分列表:< > & | ^ %

转义字符是^。所以要得到一个文字|,你应该这样做:

echo ^|

当特殊字符在变量中时,它变得有点困难。但如果你使用特殊语法,你可以像这样替换变量中的字符:

set X=A^|B

REM replace pipe character with underscore
set Y=%X:|=_%

echo %Y%
REM prints "A_B"

【讨论】:

如果您正在处理来自用户/用户系统的文件系统路径,则几乎不可能正确地转义到没有特殊字符的内容。 (文件名可以包含 %,!,^,& 等) 需要注意的是,做 ^% 是行不通的,因为 %es 你需要用另一个 % 转义(即使用 %%)。【参考方案2】:

你必须逃避 |打印 var 之前的字符。以下打印 a|b

@echo off

set x=a^|b
echo %x:|=^|%

【讨论】:

非常感谢 - 这是解决“输出变量(可能)包含管道”问题的唯一“真正”解决方案 - 实际上,“安全”脚本可能应该始终这样做。 ..【参考方案3】:

问题没有指定操作系统。对于 unix:

逃跑

echo \|

或用引号括起来

echo "|"

【讨论】:

我无法逃脱它,因为变量来自另一个命令,但引号起作用了......为什么我以前没有想到这一点......现在看看我是否可以删除所有不需要的数据相反... 在它周围加上引号会导致引号被输出。 我写这篇文章的时候实际上是在考虑unix,所以它很失败!【参考方案4】:

老问题,但有一个未提及的解决方案,更易于使用:延迟扩展

使用延迟扩展的好处是,任何内容都可以不加修改地使用,完全没有问题字符。

set "test=A|B&C,D"E^<F^>G"
setlocal EnableDelayedExpansion
echo !test!

set test       --- Works, but shows also: "test=..."
echo %test% --- This one fails

【讨论】:

您的示例对我来说仍然没有多大意义,但延迟扩展是我正在寻找的答案。谢谢!【参考方案5】:
set X=%0^|callset.bat
set Y=%X:|=_%
echo %Y%
echo %X% _ %Y%
REM activate callset | more

REM,你应该有无限管道。两次中断 CTRL+C Ctrl 中断 REM 打印“进程试图写入不存在的管道。”

【讨论】:

【参考方案6】:

Henrik's answer 如果您只是想将变量的内容回显到屏幕上,则可以正常工作,但是如果您想将包含管道符号的值通过管道传输到另一个程序中(就像我所做的那样),您需要添加更多插入符号( ^):

回显包含管道的裸文本 (|):

echo Hello ^| world

Set-and-echo 包含管道的变量 (|):

set txt=Hello ^| world
echo %txt:|=^|%

将包含管道 (|) 的裸文本回显到另一个程序中:

echo Hello ^^^| world | hexdump

产生:

000000   48 65 6c 6c 6f 20 7c 20 - 77 6f 72 6c 64 20 0a     Hello | world .

设置并回显包含管道 (|) 的变量到另一个程序

set txt=Hello ^| world
echo %txt:|=^^^|% | hexdump

产生:

000000   48 65 6c 6c 6f 20 7c 20 - 77 6f 72 6c 64 20 0a     Hello | world .

hexdump 只是一个实用程序,我必须以十六进制和 ASCII 格式转储 stdin)。

需要三个插入符号 (^^^) 的原因(我想我理解它)是因为 CMD 本质上会解析命令行两次:一次是为了识别它包含一个未转义的管道(| hexdump 位);然后每个部分在执行它们时都会被处理第二次

第一遍将echo Hello ^^^| world 变成echo ^| world(将中间位读作^^,后跟^|:转义的插入符号和转义的管道)。当它被处理时间时——在执行管道时——“幸存的”插入符号保护管道符号,以便将Hello | world输入下一个命令。

【讨论】:

以上是关于导致意外行为的批处理回显管道符号的主要内容,如果未能解决你的问题,请参考以下文章

批处理学习笔记第二课:简单批处理命令

dos批处理命令详解

批处理命令大全

批处理命令教程

批处理命令大全

[No0000A5]批处理常用命令大全