Cod*_*ith 183
另一种逃避引用的方法(尽管可能不是更好),我发现在某些地方使用的是使用多个双引号.为了使其他人的代码清晰,我将解释.
这是一套基本规则:
program param1 param2 param 3将通过四个参数program.exe:param1,param2,param,和3.program one two "three and more"将通过三个参数program.exe:one,two和three and more.hello"to the entire"world作为一个参数:helloto the entireworld."Tim says, ""Hi!"""将作为一个参数:Tim says, "Hi!"因此,有三种不同类型的双引号:打开的引号,关闭的引号和作为纯文本的引号.
这是最后一个令人困惑的线的细分:
" open double-quote group
T inside ""s
i inside ""s
m inside ""s
inside ""s - space doesn't separate
s inside ""s
a inside ""s
y inside ""s
s inside ""s
, inside ""s
inside ""s - space doesn't separate
" close double-quoted group
" quote directly follows closer - acts as plain unwrapped text: "
H outside ""s - gets joined to previous adjacent group
i outside ""s - ...
! outside ""s - ...
" open double-quote group
" close double-quote group
" quote directly follows closer - acts as plain unwrapped text: "
因此,文本有效地连接了四组字符(一个没有任何东西,但是):
Tim says, 是第一个,包裹逃避空间
"Hi!是第二个,没有包裹(没有空格)
is the third, a double-quote group wrapping nothing
"是第四个,未打开的近距离报价.
正如你所看到的,双引号组不包含任何东西仍然是必要的,因为如果没有它,下面的双引号会打开一个双引号组,而不是作为纯文本.
因此,应该认识到,因此,在内部和外部引号中,三个双引号充当纯文本未转义的双引号:
"Tim said to him, """What's been happening lately?""""
将按Tim said to him, "What's been happening lately?"预期打印.因此,总是可以可靠地使用三个引号作为逃避.
但是,在理解它时,您可能会注意到最后的四个引号可以减少到仅仅两个,因为它在技术上是添加另一个不必要的空双引号组.
以下是一些关闭它的示例:
program a b REM sends (a) and (b)
program """a""" REM sends ("a")
program """a b""" REM sends ("a) and (b")
program """"Hello,""" Mike said." REM sends ("Hello," Mike said.)
program ""a""b""c""d"" REM sends (abcd) since the "" groups wrap nothing
program "hello to """quotes"" REM sends (hello to "quotes")
program """"hello world"" REM sends ("hello world")
program """hello" world"" REM sends ("hello world")
program """hello "world"" REM sends ("hello) and (world")
program "hello ""world""" REM sends (hello "world")
program "hello """world"" REM sends (hello "world")
最后的注意事项:我没有从任何教程中读到任何内容 - 我通过实验想出了所有这些内容.因此,我的解释在内部可能不正确.尽管如此,上面的所有例子都给出了评估,从而验证了(但没有证明)我的理论.
我在Windows 7,64bit上测试了这个,只使用带参数传递的*.exe调用(不是*.bat,但我认为它的工作方式相同).
smw*_*dia 23
试试这个:
myscript """test"""
Run Code Online (Sandbox Code Playgroud)
""在参数中"转义为单个".
mou*_*sio 19
我无法快速重现这些症状:如果我尝试myscript '"test"'使用myscript.bat包含just @echo.%1或者甚至的批处理文件@echo.%~1,我会得到所有引号:'"test"'
也许你可以尝试这样的转义字符^:myscript '^"test^"'?
Lou*_*ous 12
Peter Mortensen 在对 Codesmith 的答案的评论中引用的第二份文件让我的情况变得更加清晰。该文档由 windowsinspired.com 编写。重复链接:理解 Windows 命令行参数的引用和转义的更好方法。
一些进一步的尝试和错误导致了以下指导方针:
"用插入符号转义每个双引号^。如果您希望将 Windows 命令 shell 具有特殊含义的其他字符(例如,<, >, |, &)解释为常规字符,那么也可以使用脱字符号对它们进行转义。
如果您希望程序foo接收命令行文本"a\"b c" > d并将其输出重定向到文件out.txt,则从 Windows 命令 shell 启动您的程序,如下所示:
foo ^"a\^"b c^" ^> d > out.txt
Run Code Online (Sandbox Code Playgroud)
如果foo解释\"为文字双引号,并期望使用非转义双引号来分隔包含空格的参数,则foo将该命令解释为指定一个 argument a"b c、一个 argument>和一个 argument d。
相反,如果foo将双双引号解释""为文字双引号,则将程序启动为
foo ^"a^"^"b c^" ^> d > out.txt
Run Code Online (Sandbox Code Playgroud)
引用的文档的关键见解是,对于 Windows 命令 shell,未转义的双引号会触发两种可能状态之间的切换。
一些进一步的试验和错误意味着在初始状态下,重定向(到文件或管道)被识别,插入符号^转义双引号,并且插入符号从输入中删除。在另一种状态下,无法识别重定向,并且插入符号不会转义双引号并且不会被删除。我们将这些状态分别称为“外部”和“内部”。
如果要重定向命令的输出,则命令 shell 在到达重定向时必须处于外部状态,因此重定向之前必须有偶数个未转义(通过插入符号)的双引号。 foo "a\"b " > out.txt不起作用——命令 shell 将整个内容作为其组合命令行参数传递给"a\"b " > out.txtfoo ,而不是仅传递"a\"b "并将输出重定向到out.txt。
foo "a\^"b " > out.txt也不起作用,因为插入符号^是在内部状态中遇到的,它是普通字符而不是转义字符,因此"a\^"b " > out.txt被传递给foo。
(希望)始终有效的唯一方法是使命令 shell 始终处于外部状态,因为这样重定向就可以工作。
如果您不需要重定向(或对命令 shell 具有特殊含义的其他字符),那么您可以不使用插入符号。如果foo解释\"为文字双引号,那么您可以将其称为
foo "a\"b c"
Run Code Online (Sandbox Code Playgroud)
然后foo接收"a\"b c"作为其组合参数文本,并可以将其解释为等于 的单个参数a"b c。
现在——最后——回到最初的问题。 myscript '"test"'从 Windows 命令 shell 调用会传递'"test"'到myscript。显然myscript将单引号和双引号解释为参数分隔符并将其删除。您需要弄清楚myscript接受什么作为文字双引号,然后在命令中指定它,用于^转义对 Windows 命令 shell 具有特殊含义的任何字符。鉴于这myscript在 Unix 上也可用,也许\"可以解决问题。尝试
myscript \^"test\^"
Run Code Online (Sandbox Code Playgroud)
或者,如果您不需要重定向,
myscript \"test\"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
139260 次 |
| 最近记录: |