5

我正在使用 CScript 运行 VBScript 文件,我需要将命令行传递给脚本,其中参数包含空格和引号。整个命令需要作为一个参数传递给脚本。例如:

C:\> CScript myscript.vbs //Nologo "cmd.exe /c "dir && del /q *.txt""

请注意,上面的特定命令行只是一个示例,但它确实触及了我正在尝试做的事情(即传递一个涉及运行 cmd.exe 的命令行)。但是,我正在尝试解决一般情况。

问题是 CScript 似乎在试图确定引号在哪里打开和关闭时感到困惑。至少有时。

以下脚本可能有助于解释。它只是输出传入的参数,因为它看到它们:

Dim count
For count = 0 To WScript.Arguments.Count-1
    WScript.Echo CStr(count) & " = " & WScript.Arguments.Item(count)
Next

通常,它按预期工作:

C:\> cscript myscript.vbs //Nologo "1 2 3"
0 = 1 2 3

但是当引用参数中有引号时,情况会发生变化:

C:\> cscript myscript.vbs //Nologo "1 "2 3""
0 = 1 2
1 = 3

我知道在上面的示例中,关于每个引号是打开还是关闭参数存在引入歧义,所以接下来我尝试转义内部引号,以便命令处理器将它们视为文字字符串:

C:\> cscript myscript.vbs //Nologo "1 ^"2 3^""
0 = 1 ^2
1 = 3

嗯,看起来只有当 shell 为你做 globbing 等时才有效。我怀疑 cscript^是否像 cmd.exe 那样理解为转义字符。

在双引号命令中使用单引号(例如“cmd.exe /c 'dir && cd \'”)可以正确解析为单个参数,但由于使用 /c 参数调用 cmd.exe 的情况下不起作用, 单引号是不够的。例如:

C:\> cmd /c 'dir && cd \'
''dir' is not recognized as an internal or external command,
operable program or batch file.

我想我可以遍历脚本中的所有参数并将它们连接回一个长字符串,但我会丢失它们提供的内部引号和上下文。或者,也许我确实在双引号参数中使用了单引号,并将它们映射回脚本中的双引号。但是,如果意图我不考虑的某些未来案例的单引号怎么办?由于我正在尝试解决一般情况,因此我无法做出决定。

有任何想法吗?

4

2 回答 2

4

您似乎正在尝试在参数中描述值。我建议使用引号以外的东西并加回引号。例如使用波浪号:

Dim count
For count = 0 To WScript.Arguments.Count-1
    WScript.Echo CStr(count) & " = " & replace(WScript.Arguments.Item(count),"~",chr(34))
Next

通过:

cscript myscript.vbs //Nologo "1 ~2 3~"
0 = 1 "2 3"
于 2012-04-10T15:41:09.277 回答
0

你有两个选择。

第一个很简单——使用克拉 (^) 转义引号。

C:\> CScript myscript.vbs //Nologo "cmd.exe /c ^"dir && del /q *.txt^""

The second option is to use a different delimiter. In a command like this, the shell uses a space as a delimeter between parameters. But the shell allows others like semicolons, commas, equal signs, and tabs. By implementing one of these, you wouldn't need to surround parameters with quotes because spaces would no longer break your command line.

于 2012-04-10T23:05:24.780 回答