【问题标题】:Spaces in batch script without breaking the syntax批处理脚本中的空格而不破坏语法
【发布时间】:2021-12-27 07:46:43
【问题描述】:

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

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

目标是提高可读性,不仅在使用gacutil.exe 时,而且在编写批处理命令时

【问题讨论】:

  • @echo放在gacutil /u前面看看语法结果
  • 'Microsoft.IdentityModel.Clients.ActiveDirectory' is not recognized as an internal or external command上失败
  • 但是根据您的问题,在`gacutil /u`之后您没有插入符号^?还有实际要求是什么,每行之间要三个空格吗?我,e gacutil /u Microsoft.IdentityModel.Clients.ActiveDirectory, Version=2.28.0.725... ?
  • 当前尝试如下所示,它不再输出关于语法拼写错误的失败,但似乎@echo 阻止了命令应用,因为它既不返回关于失败的消息也不返回关于成功,它仍然在正在注册的程序集列表中`@echo gacutil /u^ Microsoft.IdentityModel.Clients.ActiveDirectory,^ Version=2.48.0.725,^ Culture=neutral,^ PublicKeyToken=31bf3856ad364e35`

标签: windows batch-file cmd


【解决方案1】:

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

Windows 命令处理器cmd.exe 将双引号字符串之外的水平制表符、普通空格、逗号、分号、等号和 OEM 编码的不间断空格(十六进制值 FF 的字节)解释为参数分隔符,因为它可以在运行名称为 test.cmd 的批处理文件时看到,只在命令提示符窗口中使用命令行 @echo %0 $1 $2 $3 $4

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 toolgacutil.exe 将传递给它的字符串拆分为与cmd.exe 不同的参数字符串。逗号和等号不被解释为参数分隔符。只有正常的空格字符被解释为参数分隔符,除了正常的空格在双引号参数字符串内。

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

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

   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 逐行读取批处理文件,在读取一行时将回车+换行替换为换行。

cmd.exe 将行尾的插入符号 ^ 解释为换行符换行符的转义字符,从而将下一行与当前行连接起来,直到到达末尾批处理文件或找到未使用^ 转义的换行符。在批处理文件中的行连接过程中不会删除任何字符。

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

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

命令行开头留给gacutil的三个前导空格被cmd.exe删除,但所有其他空格都保留,因为cmd.exe无法知道它们是否对程序/脚本接下来运行很重要或不。所以在/u 之后有四个空格,在批处理文件的不同行中指定的其他字符串之间有三个空格。

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 删除,使gacutil.exe 的命令行无效。

因此,在这种情况下,不可能在多行上定义带有缩进空格的程序集名称参数字符串,因为cmd.exe 如何连接行并保留空格,以及gacutil.exe 如何拆分传递给的字符串从cmd.exe 到参数。

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

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

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

只要将整个程序集名称参数字符串括在双引号中,全局程序集缓存工具就不会出现程序集名称中逗号后的一个或多个空格的问题。出于这个原因,在程序集名称字符串的开头有一个",在末尾还有一个"。但是对于 Windows 命令处理器,两个双引号必须用 ^ 转义,否则 cmd.exe 会将每行末尾的插入符号 ^ 解释为文字字符,而不是转义字符。

cmd.exe 必须将分布在多行上的命令行解释为没有双引号中的参数字符串的行,以便将每个 ^ 解释为转义字符,而程序集名称在运行时实际上用双引号括起来最后用命令行gacutil.exe

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

是的,这很奇怪。

【讨论】:

    猜你喜欢
    • 2011-03-25
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 2016-05-17
    • 2019-04-15
    • 1970-01-01
    • 2016-07-11
    相关资源
    最近更新 更多