在批处理的输入参数中转义双引号

25
我希望能在批处理脚本中运行以下代码,该代码需要一个参数(路径)。
runas /user:abc "icacls %1 /grant Everyone:(F) /T"

但是参数%1已经包含一个"(因为它是通过上下文菜单的“发送到”传递的路径——我对此没有太多控制权)。 因此,当批处理脚本运行时,它会像这样运行:

runas /user:abc "icacls "c:\folder" /grant Everyone:(F) /T"

显然,我需要转义%1创建的"。如何对%1进行字符串操作,使其转义引号?

5个回答

26

你可以使用 \" 进行字符串转义。这里是一个包含其他一些转义字符的网站,你可能会发现它们有用:这里

要进行字符串替换:

set temp=%1
set temp=%temp:"=\"%
echo %temp%

5
如果 %1 是一个包含空格的路径,该怎么办? - broc.seib
你什么时候使用 "" 而不是 \"?我发现批处理文件只能用 "" 进行转义,而 \" 版本仅适用于非批处理程序(如用 C++ 或某些识别 \ 作为转义字符的语言编写的 runas)。因此,当将变量传递给非批处理程序时,我们只使用 \",而在传递给其他批处理脚本(或批处理函数(例如 CALL:function "parameterWith""EscapedQuote"))时则使用 "" - Mr_Moneybags
@nick 但是如果你尝试使用这行代码 SET "var1=key=\"val&ue!\"",你会得到错误信息:'ue!\""' is not recognized as an internal or external command, operable program or batch file.但是 "" 可以正常工作。 - Mr_Moneybags
@Mr_Moneybags,奇怪。我不会期望两者都能工作,因为&应该被转义为^&。我在想,也许""告诉批处理文件“不要将此字符串中的任何内容视为特殊字符”,类似于在C#中在字符串开头放置@。但我不确定,因为我已经很久没有使用批处理了。 - nick
嗨,我有同样的问题,但是上面的代码对我不起作用。有人可以帮忙吗? - SFDC_Learner

7

每个响应都涵盖了答案的一部分。使用反斜杠和引号\"将它们组合起来,你就可以得到:

runas /user:abc "icacls \"%~1\" /grant Everyone:(F) /T"

或者你可以使用双引号来转义它们:

runas /user:abc "icacls ""%~1"" /grant Everyone:(F) /T"

作为一个副注,有时候使用符号“^”可以用来转义特殊字符,如 <|>||&&&。例如:
echo ^|

但这种情况相当罕见。

双引号加倍对我不起作用,但反斜杠可以。 - SerG

2
SET myPath=%1
SET myPath=%myPath:"=\"%
runas /user:abc "icacls %myPath% /grant Everyone:(F) /T"

编辑 - 变量名从 path 更改为 myPath。PATH 是一个保留的系统变量,不应该用于除其原本目的以外的任何事情。


2
请勿使用“path”作为您的变量名称 - 它在Windows中具有特殊用途。修改该值可能会在脚本后期引起问题。将变量名从“path”更改为其他名称,例如“mypath”。编辑您的答案,然后我可以点赞它。 - dbenham

0

经过一些快速测试,这是最好的方法,因为它:

优点

  • 可以处理从tasklist输出的多个结果
  • 如果需要,可以处理带空格的应用程序名称
  • 可以轻松更改为区分大小写/不区分大小写

缺点

  • 调用多个命令,技术上较慢

代码

@echo off    
set "EXE=authy desktop.exe"
tasklist /NH /FI "imagename eq %EXE%" | find /i "%EXE%" >nul 2>&1
If %errorlevel% EQU 0 (
    echo %EXE% Is Running
) ELSE (
    echo %EXE% is Not Running
)

进一步考虑

您可以将检查 errorlevel 的格式更改为 && ( ) || ( ) 格式,而不是检查 errorlevel。此外,如果多次使用 errorlevel,则可以使用“setlocal enabledelayedexpansion”通过引用 !errorlevel! 来进行参考。

tasklist /NH /FI "imagename eq %EXE%" | find /i "%EXE%" >nul 2>&1 && (
    echo %EXE% Is Running
) || (
    echo %EXE% is Not Running
)

0
在这种情况下,甚至不需要进行搜索/替换。只需从参数中删除原始引号(使用%~1)- 然后您可以再次添加任何您想要的内容,例如转义引号。在您的示例中:
runas /user:abc "icacls \"%~1\" /grant Everyone:(F) /T"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接