批处理脚本中的空格而不破坏语法

Spaces in batch script without breaking the syntax

有没有办法在批处理脚本中在每行的开头添加多个空格而不破坏语法并保持每行的空格,如下例所示?

   gacutil /u ^
   Microsoft.IdentityModel.Clients.ActiveDirectory,^
   Version=2.28.0.725,^
   Culture=neutral,^
   PublicKeyToken=31bf3856ad364e35

我们的目标是不仅在使用 gacutil.exe 时而且在编写批处理命令时都允许更好的可读性

每个可执行文件都有自己的规则集,用于将可执行文件名后的字符串拆分为可执行文件进一步处理的参数值。

windows 命令处理器 cmd.exe 解释水平制表符、普通 space、逗号、分号、等号和 OEM 编码的不间断 space(具有十六进制值 FF 的字节)在双引号字符串之外作为参数分隔符,因为它可以在 运行 上看到名称为 test.cmd 的批处理文件,仅使用命令行 @echo %0 来自在命令提示符 window 和

test argument1,,,"argument 2";;;"argument 3 contains a comma ',' a semicolon ';' an equal sign '=' and multiple spaces"===argument4

导致输出

test argument1 "argument 2" "argument 3 contains a comma ',' a semicolon ';' an equal sign '=' and multiple spaces" argument4

,,,;;;=== 被解释为参数字符串分隔符。

global assembly cache tool gacutil.exe 将传递给它的字符串拆分为与 cmd.exe 不同的参数字符串。逗号和等号不被解释为参数分隔符。只有正常的 space 字符被解释为参数分隔符,除了正常的 space 在双引号参数字符串中。

对于 Windows 可执行文件来说,参数字符串之间的参数分隔符数量无关紧要是很常见的。因此,如果在两个参数字符串之间只使用一个 space 或多个 space 并不重要。

在批处理文件中使用以下行会发生什么?

   gacutil /u ^
   Microsoft.IdentityModel.Clients.ActiveDirectory,^
   Version=2.28.0.725,^
   Culture=neutral,^
   PublicKeyToken=31bf3856ad364e35

请先阅读:How does the Windows Command Interpreter (CMD.EXE) parse scripts?

Windows 命令处理器 cmd.exe 逐行读取批处理文件,替换回车符 return + 换行仅在读取一行时换行。

行尾的脱字符 ^cmd.exe 解释为换行符换行的转义符,导致将下一行与重复的当前行连接起来直到到达批处理文件的末尾或找到未使用 ^ 转义的换行符。在批处理文件中的行连接期间没有删除任何字符。

批处理文件中每行三个前导正常 spaces 的上述行的结果是:

gacutil /u    Microsoft.IdentityModel.Clients.ActiveDirectory,   Version=2.28.0.725,   Culture=neutral,   PublicKeyToken=31bf3856ad364e35

命令行开头留给 gacutil 的三个前导 space 已被 cmd.exe 删除,但所有其他 space 都被保留,因为 cmd.exe 不知道它们对接下来的 program/script 到 运行 是否重要。因此在 /u 之后有四个 space,在批处理文件的不同行中指定的其他字符串之间有三个 space。

gacutil.exe 现在将命令行解释为以下参数列表:

  1. /u
  2. Microsoft.IdentityModel.Clients.ActiveDirectory,
  3. Version=2.28.0.725,
  4. Culture=neutral,
  5. PublicKeyToken=31bf3856ad364e35

结果是一条错误消息,因为在这种情况下 gacutil.exe 必须是 运行,只有两个参数:

  1. 指示全局程序集缓存工具从全局程序集缓存中卸载程序集的选项/u
  2. 和程序集名称 Microsoft.IdentityModel.Clients.ActiveDirectory,Version=2.28.0.725,Culture=neutral,PublicKeyToken=31bf3856ad364e35

因此,cmd.exe 未删除的程序集名称参数字符串的各个部分之间的批处理文件中使用的缩进 space 使命令行对 gacutil.exe 无效。

出于这个原因,在这种情况下不可能在多行上定义缩进 spaces 的程序集名称参数字符串,因为 cmd.exe 如何连接这些行并保持 [=122] =]s 以及 gacutil.exe 如何将传递给它的字符串从 cmd.exe 拆分为参数。

不同的可执行文件可以将字符串拆分为不同的参数值列表,因此将可执行文件的参数以缩进 spaces 写入批处理文件中的多行可能适用于此可执行文件.

但是可以在这个用例的批处理文件中使用以下语法:

   gacutil /u ^
   ^"Microsoft.IdentityModel.Clients.ActiveDirectory,^
   Version=2.28.0.725,^
   Culture=neutral,^
   PublicKeyToken=31bf3856ad364e35^"

全局程序集缓存工具在程序集名称逗号后一个或多个 space 没有问题,只要整个程序集名称参数字符串用双引号引起来。因此,在程序集名称字符串的开头有一个 ",在末尾还有一个 "。但是对于 Windows 命令处理器,两个双引号必须使用 ^ 进行转义,否则 cmd.exe 会将每行末尾的脱字符 ^ 解释为文字字符,而不是作为转义字符。

分布在多行的命令行必须被 cmd.exe 解释为没有双引号中的参数字符串的行,以使每个 ^ 被解释为转义字符,而程序集名称是真实的用双引号括在 运行ning 最后 gacutil.exe 命令行:

gacutil /u    "Microsoft.IdentityModel.Clients.ActiveDirectory,   Version=2.28.0.725,   Culture=neutral,   PublicKeyToken=31bf3856ad364e35"

是的,这很奇怪。