Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 无法在批处理文件中转义感叹号_Batch File_Escaping - Fatal编程技术网

Batch file 无法在批处理文件中转义感叹号

Batch file 无法在批处理文件中转义感叹号,batch-file,escaping,Batch File,Escaping,我不能用^^逃避感叹号。我知道我需要使用setlocal disabledelayedexpansion或者只使用endlocal,但是我找不到正确的位置来放置它而不会出现任何错误 以下是我的脚本,用于在cmd窗口的水平中心显示文本: @echo off setlocal enabledelayedexpansion title Center Text mode 80,50 set "cmdwidth=80" :Display cls set Center=This is

我不能用
^^逃避感叹号。我知道我需要使用
setlocal disabledelayedexpansion
或者只使用
endlocal
,但是我找不到正确的位置来放置它而不会出现任何错误

以下是我的脚本,用于在
cmd
窗口的水平中心显示文本:

@echo off
setlocal enabledelayedexpansion
title Center Text
mode 80,50

set "cmdwidth=80"
:Display
cls
set Center=This is a test^^! & call :CenterText Center strLen
echo.
pause
exit

:CenterText
  if not "!%1:~%len%!"=="" set /A len+=1 & goto :CenterText
(endlocal & set %2=%len%)

goto CenterTextDisplay
:AddSpace
set "spaces=%spaces% "
goto :eof
:CenterTextDisplay
set /a "indent=(cmdwidth - strLen)/2" 
set "spaces= "
for /l %%a in (1,1,%indent%) do call :AddSpace
echo %spaces%%Center%
set "len=0"
goto :eof

这是我的代码,没有错误,但我无法正确地避开感叹号,结果是
这是一个测试
而不是
这是一个测试

每次启用延迟扩展时,当文字字符串包含感叹号时,以及当立即扩展(正常
%
扩展)在其字符串值中包含感叹号时,感叹号都会丢失(或导致其他意外结果);对于
参数(例如,
%%I
)和参数引用(例如,
%1
),也同样如此,因为所有这些都是在延迟扩展发生之前展开的。
为了避免任何此类问题,只有在实际需要时才应启用延迟扩展

在代码中,全局启用延迟扩展。变量
Center
在正确转义时实际上保留感叹号,但在
echo%spaces%%Center%%
行中展开
%Center%
后,它就会丢失

以下是改编后的剧本:

@echo关闭
setlocal DisableDelayedExpansion
标题中心文本
模式80,50
设置“cmdwidth=80”
:显示
cls
设置“中心=这是一个测试!”&调用:CenterText Center strLen
回音/
暂停
端部
退出/B
:CenterText
setlocal EnableDelayedExpansion
:CenterText\u循环
如果不是“!%~1:~%len%!”==“设置/A len+=1&goto:CenterText\u循环”
endlocal&设置“%~2=%len%”
设置/a“缩进=(cmdwidth strLen)/2”
设置“空格=”
对于(1,1,%indent%)中的/l%%a,请调用:AddSpace
回显(%spaces%%Center%)
设置“len=0”
后藤:eof
:AddSpace
设置“空格=%spaces%”
后藤:eof
除了纠正延迟扩展问题外,我还修复了以下事项:

  • exit
    更改为
    exit/B
    以仅终止批处理脚本,而不终止父
    cmd
    实例
  • echo.
    更改为
    echo/
    ,因为如果当前目录中有名为
    echo
    (无文件扩展名)的文件,则前者可能会失败
  • 通过一致引用整个赋值表达式,改进了
    set
    语法
  • %1
    更改为
    %1
    并将
    %2
    更改为
    %2
    ,以从扩展值中删除潜在的周围引号
  • 将子例程
    :AddSpace
    向下移动,以澄清执行流程并避免需要标签
    :CenterTextDisplay
    和相关的
    转到

    实际上,如果将(1,1,%indent%)do call:AddSpace中/l%%a的命令行
    替换为以下内容,您甚至可以删除该子例程:

    for /l %%a in (1,1,%indent%) do call set "spaces=%%spaces%% "
    
    这说明了延迟扩展的另一种替代方法:将变量周围的
    %
    符号加倍,并使用
    调用
    ;但这并不适用于所有情况,因为某些字符仍可能导致问题,而
    调用
    无法运行某些命令(如
    for
    if


您不需要
延迟扩展
-将
更改为
%
中的
:centertext
并丢失
endlocal
@Magoo当我将
更改为
%
时,批处理文件不会运行,只是crashes@Magoo,由于嵌套扩展(
!%1!
)的原因,此处实际上需要延迟扩展。。。