【问题标题】:How to pass redirect symbols (< and >) to a Windows batch file function?如何将重定向符号(< 和 >)传递给 Windows 批处理文件函数?
【发布时间】:2014-01-28 12:57:04
【问题描述】:

假设这个批处理文件

call :SomeFunction "a string with an > arrow"

goto:eof

:SomeFunction
  echo %~1
goto:eof

这个的输出是

调用 :SomeFunction "带有 > 箭头的字符串" 回显带有 1> 箭头的字符串 转到:eof 转到:eof

并创建一个名为arrow 的文件,其中包含a string with an。注意1&gt;

在这种情况下,如何防止命令处理器将 &gt; 解释为重定向符号? (提示:我试过^&gt;,但不是这样。)

编辑:其他运营商(|&amp;)当然也会受到影响。

【问题讨论】:

标签: windows batch-file cmd


【解决方案1】:

您可以为此使用FOR /F 命令,而不是:

echo %~1

使用这个:

FOR /F "delims=" %%i IN ("%~1") DO echo %%i

编辑:请注意,现在您需要处理在传递以双引号分隔的参数时的奇怪转义行为。例如"a^2" 将被转义"a^^2",无论你尝试使用"a^^2""a\^2"。您可以做的(根据您自己的评论)是使用临时变量并进行转义(然后删除双引号):

set TEMP=%TEMP:>=^>%

如果你不想在意逃跑,你也可以试试:

set "tmp="many \ ^ > ' characters and quotes""

注意用双引号将set 参数和字符串中的许多特殊 字符括起来。在这种情况下,tmp 环境变量的字面意思是:"many \ ^ &gt; ' characters and quotes",您可以简单地将其用作:

FOR /F "delims=" %%1 IN (%tmp%) DO echo %%1

注意%1 而不是"%~1"。现在让我们把它变得更复杂。如果您在字符串中需要双引号 " 则某些字符将不会被转义(例如 &|)。您可以简单地删除引用:

set "tmp=many \ ^ > ' | & characters and quotes"

使用:

FOR /F "delims=" %%1 IN ("%tmp%") DO echo %%1

或者

FOR /F "delims== tokens=2" %%1 IN ('set tmp') DO echo %%1

不要忘记,如果您指定 usebackq 选项,则可以使用反提示分隔 FOR 字符串。您可以使用临时文件或...更好...PowerShell 脚本...

【讨论】:

  • 太棒了,这行得通。它将可能在字符串中的转义字符(^)加倍,但是......
  • @Tomalak 是的,调用对于转义其参数很糟糕(所以你可能需要 (%1) 而不是 ("%~1"))无论如何 some 个字符需要被逃脱。 AFAIK 没有真正的“原始”方式来传递参数而不转义(除非您使用临时文件)。
  • @Tomalak 我同意。它在没有任何连贯性的情况下进行了扩展,并且有很多孔和暗角(兼容性?)。这就是我喜欢 PS 的原因!
  • @Tomalak 不仅可以跳过转义并保留FOR,如果您使用set "tmp="many \ ^ &gt; ' characters and quotes"" 设置临时变量(请注意开头和结尾的双引号以及value的内引号>)。
  • 如果可以的话,我会再次为您的编辑投票。很有启发性!
【解决方案2】:

Call^ 做一些时髦的事情,但这很有效。

@echo off
set "var=a string with an ^> arrow"
call :SomeFunction 
pause
goto:eof

:SomeFunction
  echo %var%
goto:eof

【讨论】:

  • 抱歉,但这不是解决方案。我想继续使用函数参数(而不是全局变量)
  • +1 这不是最好的解决方案,但它展示了如何以一般方式解决问题
【解决方案3】:

就像 foxidrive 提到的那样,CALL 会修改插入符号,因此不可能构建一个防弹的方法来通过 CALL 按值传输参数。
但是你可以通过引用来使用参数。

@echo off
set "var=a string with a caret^ and an > arrow"

call :SomeFunc var
exit /b

:SomeFunc
setlocal EnableDelayedExpansion
set "param1=!%1!"
echo !param1!
exit /b

我在这里使用延迟扩展,因为这是以安全方式处理任何可变内容的最佳方式

【讨论】:

    猜你喜欢
    • 2019-05-10
    • 2018-03-28
    • 2015-05-12
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    相关资源
    最近更新 更多