当我在cmd脚本中设置了 setlocal ENABLEDELAYEDEXPANSION
后,有没有办法转义一个想要作为命令参数使用的感叹号(!)?
@echo off
setlocal ENABLEDELAYEDEXPANSION
echo I want to go out with a bang!
echo I still want to go out with a bang^!
当我在cmd脚本中设置了 setlocal ENABLEDELAYEDEXPANSION
后,有没有办法转义一个想要作为命令参数使用的感叹号(!)?
@echo off
setlocal ENABLEDELAYEDEXPANSION
echo I want to go out with a bang!
echo I still want to go out with a bang^!
这就是我找到的(^^)
@echo off
setlocal ENABLEDELAYEDEXPANSION
echo I want to go out with a bang^^!
通常情况下,^^!
是有效的,但是在引号中,你只需要使用 ^!
。
echo I want to go out with a bang^^!
echo He said "Bang^!"
这是批处理解析器的转义机制导致的结果。
首先,解析器会解析一行,并且插入符号(^)会转义下一个字符,对于&|<>()"<linefeed>
,在引号外面有影响,但在引号内部,所有字符都是“正常”的,插入符本身没有效果。
使用延迟扩展功能后,会跟随额外的解析步骤,这时插入符也是下一个字符的转义字符,但只会影响!
和^
,并且在此解析步骤中忽略了引号。只有当该行中至少有一个!
时,才会执行此额外的解析步骤。
setlocal DisableDelayedExpansion
echo DisableDelayedExpansion
echo one caret^^
echo one caret^^ bang! "boom^!"
echo(
setlocal EnableDelayedExpansion
echo EnableDelayedExpansion
echo one caret^^
echo none caret^^ bang^^! "boom^!"
---- 输出 ------
DisableDelayedExpansion
one caret^
one caret^ bang! "boom^!"
EnableDelayedExpansion
one caret^
none caret bang! "boom!"
编辑
下面是一个稍微修改过的示例,更好地说明了取决于上下文所需的各种转义排列组合。唯一需要不寻常转义的情况是最后一个示例,当启用延迟扩展并且行中存在至少一个!
时。
@echo off
setlocal DisableDelayedExpansion
echo DisableDelayedExpansion
echo caret^^ "caret^"
echo caret^^ bang! "caret^ bang!"
echo(
setlocal EnableDelayedExpansion
echo EnableDelayedExpansion
echo caret^^ "caret^"
echo caret^^^^ bang^^! "caret^^ bang^!"
-- 输出 --
DisableDelayedExpansion
caret^ "caret^"
caret^ bang! "caret^ bang!"
EnableDelayedExpansion
caret^ "caret^"
caret^ bang! "caret^ bang!"
DISABLEDELAYEDEXPANSION
和ENABLEDELAYEDEXPANSION
状态。@echo off
setlocal DISABLEDELAYEDEXPANSION
set DB_password=encrypt!Pws
echo %DB_password%
SETLOCAL ENABLEDELAYEDEXPANSION
echo !DB_password!
谢谢。补充一下,如果脚本中的一个变量包含一个“!”,那么以下方法会按原样渲染该值:
@echo off SETLOCAL EnableDelayedExpansion set /P omg=输入包含感叹号的值: echo 传统: %omg% echo 替代方式: !omg! pause