导致意外行为的批处理回显管道符号
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
输入下一个命令。
【讨论】:
以上是关于导致意外行为的批处理回显管道符号的主要内容,如果未能解决你的问题,请参考以下文章