两个几乎相同的批处理脚本之一中存在语法错误:“)”无法在此处进行语法处理

2024-02-13

我正在尝试设置 Jenkins 服务器来自动构建 Unity。

因此,我编写了两个(在我看来)基本相同的批处理脚本。

这两个脚本均由 Jenkins 通过Execute Windows batch command步骤使用

Command: E:\unityImport.bat

之后一秒钟Execute Windows batch command步骤使用

Command: E:\unityBuild.bat

它们都有相同的开头,因为我需要收集一些文件路径,特别是项目的统一版本。因此,在这两个脚本中,我使用完全相同的方式来解析和字符串分割项目版本。它们之间唯一的不同是第一个启动 Unity 并导入专用的unitypackage(其中包含下一步要执行的方法)到项目中,而第二个再次启动 Unity 来执行实际构建(不幸的是,它不能一次性工作...Unity 似乎尝试在之前执行该方法这unitypackage是进口的)。

但是,第二个脚本总是因语法错误而失败

“)”在这里无法进行语法处理。


我试图实现的是

  1. 读出文件内容%WORKSPACE%\ProjectSettings\ProjectVersion.txt

    SET /p TEST=<%WORKSPACE%\ProjectSettings\ProjectVersion.txt
    

    内容为%TEST%通常看起来像

    m_EditorVersion: 2019.3.4f1
    

    and ECHO. ProjectVersion.txt = %TEST%好像

    ProjectVersion.txt = m_EditorVersion: 2019.3.4f1
    
  2. 字符串分割,以便仅获取包含版本号的最后一部分

    for %%x in (%TEST::= %) do (
        SET "VALUE=%%x"
        SET "UNITY_VERSION=!VALUE:~0,-2!" 
    )
    

    so %UNITY_VERSION%通常包含例如2019.3.4。我不会分开更多,因为还有带有两位数字的 Unity 版本,例如2018.4.18

  3. 字符串分割在.为了只获得主要版本号

    for /f "tokens=1,2 delims=." %%a in ("%UNITY_VERSION%") do (
        SET "A=%%a"
        SET "B=%%b"
    )
    SET "UNITY_VERSION=%A%.%B%"
    

    这导致%UNITY_VERSION%例如2019.3

  4. 最后搜索所有已安装的 Unity 版本是否存在所需版本

    set "UNITY_FOLDER="
    for /f "delims=" %%a in ('dir /b E:\Unity\%UNITY_VERSION%*') do (
        set "UNITY_FOLDER=%%a"
    )
    

    此后,我们要么找到给定版本的有效 Unity 安装文件夹,要么找不到。


这是脚本。

Import(这按预期工作)

@ECHO OFF
CLS
ECHO.

cd %WORKSPACE%

IF NOT EXIST %WORKSPACE%\ProjectSettings\ProjectVersion.txt (
    EXIT 1
)

SETLOCAL ENABLEDELAYEDEXPANSION

SET /p TEST=<%WORKSPACE%\ProjectSettings\ProjectVersion.txt
ECHO. ProjectVersion.txt = %TEST%

for %%x in (%TEST::= %) do (
    SET "VALUE=%%x"
    SET "UNITY_VERSION=!VALUE:~0,-2!" 
)

for /f "tokens=1,2 delims=." %%a in ("%UNITY_VERSION%") do (
    SET "A=%%a"
    SET "B=%%b"
)

SET "UNITY_VERSION=%A%.%B%"
ECHO. Project Unity Version = %UNITY_VERSION%

set "UNITY_FOLDER="
for /f "delims=" %%a in ('dir /b E:\Unity\%UNITY_VERSION%*') do (
    set "UNITY_FOLDER=%%a"
)

IF "%UNITY_FOLDER%"=="" (
    EXIT 1
)

ECHO. Using Unity Version %UNITY_FOLDER%

ECHO. Running:
ECHO. E:\Unity\%UNITY_FOLDER%\Editor\Unity.exe -quit -batchmode -projectPath %WORKSPACE% -logFile - -importPackage E:\UnityBuildPackage\AutoBuilder.unitypackage

E:\Unity\%UNITY_FOLDER%\Editor\Unity.exe -quit -batchmode -projectPath %WORKSPACE% -logFile - -importPackage E:\UnityBuildPackage\AutoBuilder.unitypackage

IF NOT %errorlevel% equ 0 (
    EXIT 1
) 

EXIT 0

Build(这会因语法错误而失败,我将用REM HERE IT BREAKS! ...实际脚本中不存在)

@ECHO OFF
CLS
ECHO.

cd %WORKSPACE%

IF NOT EXIST %WORKSPACE%\ProjectSettings\ProjectVersion.txt (
    EXIT 1
)

SETLOCAL ENABLEDELAYEDEXPANSION

SET /p TEST=<%WORKSPACE%\ProjectSettings\ProjectVersion.txt
ECHO. ProjectVersion.txt = %TEST%

REM HERE IT BREAKS! The before echo is the last I see before getting the syntax error

for %%x in (%TEST::= %) do (
    SET "VALUE=%%x"
    SET "UNITY_VERSION=!VALUE:~0,-2!" 
)

for /f "tokens=1,2 delims=." %%a in ("%UNITY_VERSION%") do (
    SET "A=%%a"
    SET "B=%%b"
)

SET "UNITY_VERSION=%A%.%B%"
ECHO. Project Unity Version = %UNITY_VERSION%

set "UNITY_FOLDER="
for /f "delims=" %%a in ('dir /b E:\Unity\%UNITY_VERSION%*') do (
    set "UNITY_FOLDER=%%a"
)

IF "%UNITY_FOLDER%"=="" (
    EXIT 1
)

ECHO. Using Unity Version %UNITY_FOLDER%

...

我认为其余的并不重要,因为正如我在控制台中看到的那样,它已经在例如之后中断了。

项目版本.txt = 2019.3.4f1

“)”在这里无法进行语法处理。


有没有人看到这个错误,或者 Jenkins 是否有某些东西导致第二个脚本因语法错误而失败,即使据我所知它们基本上是相同的?


代码存在多个小问题,我在我对批处理文件的建议下逐一解释这些问题。

任务要获得UNITY_FOLDER根据UNITY_VERSION如文件中定义的ProjectVersion.txt使用以下代码可以更有效地完成:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

if not defined WORKSPACE (
    echo ERROR: Environment variable WORKSPACE is not defined.
    exit /B 1
)

if not exist "%WORKSPACE%\ProjectSettings\ProjectVersion.txt" (
    echo ERROR: File "%WORKSPACE%\ProjectSettings\ProjectVersion.txt" does not exist.
    exit /B 1
)

set "UNITY_FOLDER="
set "UNITY_VERSION="
for /F "usebackq tokens=2-4 delims=. " %%I in ("%WORKSPACE%\ProjectSettings\ProjectVersion.txt") do (
    if not "%%~K" == "" (
        for /F "delims=abcdef" %%L in ("%%~K") do (
            set "UNITY_VERSION=%%~I.%%~J.%%~L"
            for /D %%M in ("E:\Unity\%%~I.%%~J*") do set "UNITY_FOLDER=%%M"
        )
    )
)

if not defined UNITY_VERSION (
    echo ERROR: Failed to determine unity version from "%WORKSPACE%\ProjectSettings\ProjectVersion.txt".
    exit /B 1
)
if not defined UNITY_FOLDER (
    echo ERROR: Failed to find a folder in "E:\Unity" for unity version %UNITY_VERSION%.
    exit /B 1
)

echo Found for unity version %UNITY_VERSION% the folder "%UNITY_FOLDER%".

cd /D "%WORKSPACE%" 2>nul
if errorlevel 1 (
    echo ERROR: Failed to set "%WORKSPACE%" as current folder.
    exit /B
)
rem Other commands to execute.

endlocal

该批处理文件首先使用命令设置该批处理文件所需的执行环境SETLOCAL.

环境变量的存在WORKSPACE接下来由批处理文件进行验证。该环境变量应由 Jenkins 在该批处理文件之外定义。如果缺少此重要环境变量的定义,则会输出错误消息。

然后检查文本文件是否存在,如果不存在则打印一条错误消息,并以退出代码 1 退出批处理文件。

两个环境变量UNITY_FOLDER and UNITY_VERSION如果在批处理文件之外偶然定义,则被删除。

接下来处理文本文件,该文件应仅包含一个包含感兴趣数据的非空行。否则,有必要更改代码以计算第一个子字符串(如果相等)m_EditorVersion:在执行其他命令之前。

FOR有选项/F解释包含在中的集合"默认情况下作为字符串进行处理。但在这种情况下,字符串"应解释为文件的完整限定文件名,其内容应逐行处理FOR。因此该选项usebackq用于获取所需的文件内容处理行为。

FOR在处理文件内容时总是忽略空行。因此,文本文件顶部是否包含一个或多个空行并不重要。

FOR默认情况下,使用普通空格和水平制表符作为字符串分隔符将一行拆分为子字符串。如果第一个空格/制表符分隔字符串以分号开头,分号是删除所有前导空格/制表符后的默认行结束符,则该行也将被忽略FOR就像一个空行。最后,只有第一个空格/制表符分隔的字符串将被分配给指定的循环变量I.

这里不需要这种默认的行处理行为,因为只是m_EditorVersion:分配给指定的循环变量I是不足够的。因此该选项delims=. 用于将线条按点和空格分开。选项tokens=2-4通知FOR第二个空格/点分隔的子字符串2019应该分配给循环变量I,第三个空格/点分隔的子字符串3到下一个循环变量J这是中的下一个字符ASCII 表 https://www.asciitable.com/和第四个空格/点分隔的子字符串4f1到下一个循环变量K.

这里重要的是要指定delims=. 在选项参数字符串的末尾,以空格字符作为最后一个字符,因为空格字符否则会被解释为要忽略的选项分隔字符,就像之间的空格一样usebackq and tokens=2-4和之间的空间tokens=2-4 and delims=. 。事实上,也可以编写不带空格的选项,例如"usebackqtokens=2-4delims=. ",但这使得带有选项的参数字符串难以阅读。

默认行尾定义eol=;可以保留在这里,因为与 Unity 版本一致ProjectVersion.txt在 0 个或多个空格/点之后没有分号,因此永远不会被忽略。

FOR在行中至少找到分配给循环变量的第二个空格/点分隔字符串后运行命令块中的命令I,即非空字符串被分配给指定的循环变量I。但只有当统一版本的所有三个部分都由以下方式确定时,才应执行命令FOR并分配给循环变量I, J and K。因此,进行简单的字符串比较来验证循环变量值引用%%~K不会扩展为空字符串,因为这意味着没有从文件中读取 Unity 版本的足够部分。

我不知道什么f1编辑器版本末尾的意思是。那么再来一张FOR有选项/F用于分割string 4f1 (no usebackq在包含在的字符串上") 使用字符转换为子字符串abcdef(小写十六进制字符)作为字符串分隔符并分配给指定的循环变量L只是第一个子字符串。这应该永远不会失败,所以环境变量UNITY_VERSION定义为2019.3.4.

第三FOR在第二个内部执行FOR尽管由于没有引用循环变量,它也可能在外部L。因此,这里也可以使用以下代码,得到相同的结果。

for /F "usebackq tokens=2-4 delims=. " %%I in ("%WORKSPACE%\ProjectSettings\ProjectVersion.txt") do (
    if not "%%~K" == "" (
        for /F "delims=abcdef" %%L in ("%%~K") do set "UNITY_VERSION=%%~I.%%~J.%%~L"
        for /D %%M in ("E:\Unity\%%~I.%%~J*") do set "UNITY_FOLDER=%%M"
    )
)

FOR有选项/D和一组包含* (or ?) 导致在指定目录中搜​​索E:\Unity对于名称开头的非隐藏目录2019.3。每个非隐藏目录E:\Unity匹配通配符模式2019.3*首先用完整限定名称(驱动器+路径+名称)依次分配给循环变量M和环境变量旁边UNITY_FOLDER. FOR永远不会将文件/文件夹字符串包含在其中"这就是为什么%%M可以在这里使用%%~M没有必要。分配给循环变量的文件夹名称M从未包含在"在这种情况下。所以环境变量UNITY_FOLDER包含与文件系统返回的通配符模式匹配的最后一个文件夹以及完整路径。这意味着多个文件夹名称与通配符模式匹配2019.3*文件系统决定最后分配给哪个文件夹名称UNITY_FOLDER。 NTFS 在其主文件表中存储按本地特定字母顺序排序的目录项,而 FAT、FAT32 和 exFAT 在其文件分配表中存储未排序的目录项。

Note:如果实际上并不需要编辑器版本的第三个数字,因为它看起来像有问题的代码,也可以使用:

for /F "usebackq tokens=2-4 delims=. " %%I in ("%WORKSPACE%\ProjectSettings\ProjectVersion.txt") do (
    if not "%%~J" == "" (
        set "UNITY_VERSION=%%~I.%%~J"
        for /D %%K in ("E:\Unity\%%~I.%%~J*") do set "UNITY_FOLDER=%%K"
    )
)

如果代码可以成功确定 Unity 版本并找到匹配的 Unity 文件夹,则会进行两项附加检查。

The echo批处理文件底部的命令行仅用于验证运行此批处理文件的结果WORKSPACE在命令提示符窗口中的批处理文件之外定义,一切都按预期工作。

无需将工作区目录设为当前目录直至批处理文件末尾,但我添加了代码来验证将当前目录更改为工作区目录是否确实成功完成。


问题 1:文件/文件夹参数字符串未用引号引起来

运行时的帮助输出命令提示符 https://www.howtogeek.com/235101/10-ways-to-open-the-command-prompt-in-windows-10/ cmd /?最后一页的最后一段解释了包含空格或这些字符之一的文件/文件夹参数字符串&()[]{}^=;!'+,`~需要用直双引号引起来。因此,建议始终将不带路径或带路径的文件/文件夹名称括起来",尤其是由环境变量动态定义或从文件系统读取的一个或多个部分。

所以下面的命令行不太好:

cd %WORKSPACE%
IF NOT EXIST %WORKSPACE%\ProjectSettings\ProjectVersion.txt
SET /p TEST=<%WORKSPACE%\ProjectSettings\ProjectVersion.txt

更好的是使用:

cd "%WORKSPACE%"
IF NOT EXIST "%WORKSPACE%\ProjectSettings\ProjectVersion.txt"
SET /p TEST=<"%WORKSPACE%\ProjectSettings\ProjectVersion.txt"

可以在运行时读取简短的帮助输出cd /?该命令CD不会将空格字符解释为参数分隔符,就像 Windows 命令处理器的大多数其他内部命令的情况一样cmd.exe或目录中的可执行文件%SystemRoot%\System32默认安装的,也属于Windows命令 https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands据微软称。但是更改当前目录会因省略而失败"如果目录路径偶然包含一个&符号,因为&在双引号参数字符串之外已经被解释为cmd.exe as AND执行之前的运算符CD正如我的回答中所描述的单行包含多个命令 https://stackoverflow.com/a/25344009/3074564.

最好利用周边"在每个可能包含空格或的参数字符串上&()[]{}^=;!'+,`~或重定向运算符<>|Windows 命令处理器应将其解释为参数字符串的文字字符。嗯,方括号对于 Windows 命令处理器不再有特殊含义。[]由于历史原因而在列表中COMMAND.COMMS-DOS 的第一个版本并不总是将它们解释为文字字符。


问题 2:单个命令使用命令块

Windows 命令处理器主要用于

  • 打开批处理文件,
  • 从批处理文件中从先前记住的字节偏移量或第一行的偏移量 0 处读取一行,
  • 解析和预处理这一行,
  • 关闭批处理文件,不再需要读取任何行,
  • 记住批处理文件中的当前字节偏移量,
  • 执行命令行。

命令的帮助输出IF跑步时if /?在第一页顶部显示一般语法,条件为真时执行的命令与命令位于同一行IF。命令的帮助输出FOR跑步时for /?在第一页顶部显示一般语法,在每个循环迭代中执行的命令与命令位于同一行FOR。因此,这个推荐的语法应该用于IF条件和一个FOR只需执行一个命令的循环。

让我们看看 Windows 命令处理器如何解释以下内容IF环境变量条件WORKSPACE被定义为C:\Temp:

IF NOT EXIST %WORKSPACE%\ProjectSettings\ProjectVersion.txt (
    EXIT 1
)

仅包含这三行的批处理文件会导致执行:

IF NOT EXIST C:\Temp\ProjectSettings\ProjectVersion.txt (EXIT 1 )

因此 Windows 命令处理器检测到有一个以(,从批处理文件中读取更多行直至匹配),发现命令块仅由一个命令行组成,因此将三行合并为一个命令行。

因此,通过在批处理文件中写入,可以稍微加快批处理文件的处理速度:

IF NOT EXIST "%WORKSPACE%\ProjectSettings\ProjectVersion.txt" EXIT /B 1

然后需要更少的CPU指令来执行cmd.exe.

IF NOT EXIST "C:\Temp\ProjectSettings\ProjectVersion.txt" EXIT /B 1

但是,使用命令块始终可以使批处理文件的代码具有更好的可读性。

如果可以避免对批处理文件进行大量文件打开、读取、关闭操作(有时会对批处理文件产生巨大影响),则将批处理文件的整个代码或经常执行的部分代码放入一个命令块中甚至可能很有用。总执行时间如下所示为什么 GOTO 循环比 FOR 循环慢得多并且还依赖于电源? https://stackoverflow.com/questions/53362979/

也可以看看Windows 命令解释器 (CMD.EXE) 如何解析脚本? https://stackoverflow.com/questions/4094699/


问题 3:ECHO。可能会导致不良行为

DosTips 论坛主题解释说ECHO.可能无法输出文本或空行。的用法ECHO/如果下一个字符不是更好?最好的是ECHO(.

分隔命令的字符ECHO如果保证后面有文本要输出,则从字符串到输出可以是标准参数分隔符空格ECHO 喜欢ECHO ProjectVersion.txt = %TEST%.

ECHO/最好输出一个空行。

ECHO(最好是如果接下来有一个环境变量引用或循环变量引用,之前根本没有确定环境变量是否被定义,或者循环变量存在一个不以问号开头的非空字符串。


问题 4:使用 SET /P 从文本文件中读取一行

可以使用set /P阅读first文本文件中的行并将该行分配给环境变量,如下所示:

SET /p TEST=<%WORKSPACE%\ProjectSettings\ProjectVersion.txt

但文本文件must将要分配给文件顶部的环境变量的文本。文本文件顶部的空行不会向环境变量分配任何内容,这意味着如果环境变量TEST已经定义了,它的值根本没有改变,如果环境变量TEST之前没有定义,执行后仍然没有定义SET.

最好使用命令FOR有选项/F处理文本文件的内容。


问题 5:使用不带选项 /B 的命令 EXIT

命令EXIT退出正在处理批处理文件的 Windows 命令进程。它始终有效,但仍应避免使用EXIT没有选项/B在大多数批处理文件中。

一个批处理文件,其中EXIT没有/B不带或带退出代码的执行方式为cmd.exe结果是cmd.exe总是自行终止,即使在cmd.exe使用选项隐式或显式启动/K在完成命令、命令行或批处理文件的执行后保持命令进程运行,并且独立于批处理文件调用层次结构。

一个批处理文件EXIT没有选项/B因此很难debug https://stackoverflow.com/a/42448601/3074564因为即使在命令提示符窗口中运行批处理文件而不是双击它来查看错误消息,命令进程和控制台窗口也会关闭cmd.exe到达命令行EXIT.


问题 6:批处理文件依赖于外部定义的环境

设计良好的批处理文件不依赖于批处理文件外部定义的执行环境。这两个批处理文件使用的命令具有仅在启用命令扩展时才可用的功能。默认情况下启用命令扩展,默认情况下禁用延迟环境变量扩展,但如果批处理文件自己定义执行环境并在退出之前恢复以前的执行环境,那就更好了。这可以确保批处理文件始终按设计工作,即使调用该批处理文件的另一个批处理文件设置了不同的执行环境也是如此。

所以之后@echo off以确保ECHO模式关闭后下一个命令行应该是:

setlocal EnableExtensions DisableDelayedExpansion

那么批处理文件肯定是在预期的环境中执行的。命令endlocal应位于批处理文件的末尾以恢复初始执行环境。但 Windows 命令处理器隐式运行endlocal在退出每个执行的批处理文件的处理之前setlocal不执行匹配endlocal在退出批处理文件处理之前。

的处决setlocal /? and endlocal /?结果显示这两个命令的帮助。更好的解释可以在这个答案 https://stackoverflow.com/a/67039507/3074564有关命令的更多详细信息SETLOCAL and ENDLOCAL.

的用法setlocal在批处理文件的顶部设置所需的执行环境和endlocal在批处理文件底部恢复初始执行环境必须明智地完成,以防批处理文件应通过环境变量将结果返回到初始执行环境,例如调用当前执行的批处理文件的父批处理文件。


问题 7:字母的用法ADFNPSTXZadfnpstxz作为循环变量

命令的帮助FOR运行时输出for /?描述可用于引用循环变量值的修饰符。

   %~I         - expands %I removing any surrounding quotes (")
   %~fI        - expands %I to a fully qualified path name
   %~dI        - expands %I to a drive letter only
   %~pI        - expands %I to a path only
   %~nI        - expands %I to a file name only
   %~xI        - expands %I to a file extension only
   %~sI        - expanded path contains short names only
   %~aI        - expands %I to file attributes of file
   %~tI        - expands %I to date/time of file
   %~zI        - expands %I to size of file
   %~$PATH:I   - searches the directories listed in the PATH
                  environment variable and expands %I to the
                  fully qualified name of the first one found.
                  If the environment variable name is not
                  defined or the file is not found by the
                  search, then this modifier expands to the
                  empty string

可以组合修饰符以获得复合结果:

   %~dpI       - expands %I to a drive letter and path only
   %~nxI       - expands %I to a file name and extension only
   %~fsI       - expands %I to a full path name with short names only
   %~dp$PATH:I - searches the directories listed in the PATH
                  environment variable for %I and expands to the
                  drive letter and path of the first one found.
   %~ftzaI     - expands %I to a DIR like output line

修饰符被解释为不区分大小写,这意味着%~FI是相同的%~fI而循环变量的解释始终区分大小写,这意味着循环变量I与循环变量的解释不同i.

建议避免使用字母ADFNPSTXZadfnpstxz作为循环变量,尽管这些字母也可以用作循环变量,特别是当循环变量引用与字符串连接时,如下面的批处理文件命令行示例所示。

for %%x in ("1" 2,3;4) do echo %%~xx5 = ?

直接在命令提示符窗口中执行的相同示例:

for %x in ("1" 2,3;4) do @echo %~xx5 = ?

输出一般(并非总是):

5 = ?
5 = ?
5 = ?
5 = ?

但使用输出更有意义I在批处理文件中:

for %%I in ("1" 2,3;4) do echo %%~Ix5 = ?

直接在命令提示符窗口中执行的相同命令行:

for %I in ("1" 2,3;4) do @echo %~Ix5 = ?

在这种情况下,输出始终是:

1x5 = ?
2x5 = ?
3x5 = ?
4x5 = ?

所以无法使用ADFNPSTXZadfnpstxz作为循环变量 if

  1. 循环变量值是用修饰符引用的,这意味着循环变量值引用以%~(命令提示符窗口)或%%~(批处理文件)和
  2. 循环变量值引用与一个字符串连接,该字符串的第一个字符与循环变量所用的字母相同。

所以在命令提示符窗口中工作正常的是:

for %x in (1 2,3;4) do @echo %xx5 = ?      & rem Condition 1 is not true.
for %n in ("1" 2,3;4) do @echo %~nx5 = ?   & rem Condition 2 is not true.
for %x in ("1" 2,3;4) do @echo %~x+5 = ?   & rem Condition 2 is not true.

但是,使用可用于引用带修饰符分配给循环变量的字符串值的字母时,可读性不佳。

在命令提示符窗口中使用的可读性示例:

for %i in (*) do @echo %~si
for %f in (*) do @echo %~sf
for %i in (*) do @echo %~sni
for %f in (*) do @echo %~snf

在这种情况下i and f两者都工作并且输出是相同的,独立于使用i or f。但更容易看出修饰符是什么(s and n)以及使用时的循环变量是什么i并不是f为循环变量。

也可以使用除字母之外的其他 ASCII 字符,对于 Windows 命令处理器没有特殊含义,例如#如果不使用则作为循环变量FOR有选项/F将多个子字符串分配给多个循环变量。


问题 8:FOR 处理不带通配符的集合

让我们看看使用以下代码到底会发生什么:

setlocal EnableExtensions EnableDelayedExpansion
set "TEST=m_EditorVersion: 2019.3.4f1"
for %%x in (%TEST::= %) do (
    SET "VALUE=%%x"
    SET "UNITY_VERSION=!VALUE:~0,-2!" 
)
endlocal

字符串替换%TEST::= %结果将每个冒号替换为分配给环境变量的字符串中的空格TEST在解析FOR命令行及其命令块。所以字符串

m_EditorVersion: 2019.3.4f1

becomes

m_EditorVersion  2019.3.4f1

接下来 Windows 命令处理器替换了之间的两个空格m_EditorVersion and 2019.3.4f1通过一个空格作为清理。所以要处理的集合for最终在解析和预处理命令行之后for及其命令块:

m_EditorVersion 2019.3.4f1

该集合既不包含* nor ?。由于这个原因,命令FOR将集合解释为两个简单的空格分隔字符串以分配给指定的循环变量x一个接着一个,并对这两个字符串执行命令块中的命令两次。

第一次迭代时m_EditorVersion分配给环境变量VALUE and m_EditorVersi到环境变量UNITY_VERSION。这并不是真正想要的,但是FOR再次运行这两个命令,这次是2019.3.4f1分配给循环变量x。所以在第二次循环迭代中2019.3.4f1分配给环境变量VALUE and 2019.3.4到环境变量UNITY_VERSION.

UNITY_VERSION最终用所需的字符串定义,但是可以做得更好,如本答案顶部所示和解释。

我不太清楚为什么for命令行结果出现错误消息:

“)”在这里无法进行语法处理。

这种事不应该发生FOR循环播放m_EditorVersion: 2019.3.4f1被分配给环境变量TEST.

Either TEST定义了一个字符串,导致执行第二个批处理文件时出现语法错误,尽管根据说明不应出现这种情况,或者存在问题(解释为命令块的开头,并且 Windows 命令处理器无法找到匹配的)这标志着命令块的结束。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

两个几乎相同的批处理脚本之一中存在语法错误:“)”无法在此处进行语法处理 的相关文章

  • 忽略批处理文件中的百分号

    我有一个批处理文件 可将文件从一个文件夹移动到另一个文件夹 批处理文件是由另一个进程生成的 我需要移动的一些文件中包含字符串 20 move y myserver myfolder file 20name txt myserver othe
  • Jenkins 文本参数 - 特殊字符乱码(不需要的变量替换)

    我在 Jenkins Linux 下 有一份工作构建参数 https wiki jenkins ci org display JENKINS Parameterized Build类型为 文本 我使用参数来形成在构建过程中使用的文件的内容
  • 如何通过 DOS 批处理命令发送电子邮件?

    我在 DOS 中有一个批处理文件 可以进行一些检查 完成后我需要发送一封电子邮件 我在 interwebz 上找到了一些解决方案 但大多数都是第三方的 或者只是在 Outlook 中打开新邮件 我需要命令来发送完整的电子邮件 而无需任何人工
  • .bat 文件将文件排序到文件夹中

    对于我的图片集 我希望文件夹中的所有图片按日期自动分类到文件夹中 幸运的是 这些文件已经以时间戳命名 2012 07 15 12 21 06 jpg 2012 07 15 12 21 26 jpg 2012 07 16 12 12 50 j
  • Gitlab 合并请求事件不触发 Jenkins 多分支管道

    我正在尝试在合并请求事件上使用 GitLab Webhook 触发 Jenkins 多分支管道作业 当我测试 Webhook 时 我收到以下消息 Hook 执行成功但返回 HTTP 409 当我设置不同的 GitLab Webhook 例如
  • 使用 .bat 通过文件资源管理器打开文件夹

    我应该使用什么命令在程序末尾打开指定路径 start c Yaya yoyo 不管用 你可以这样尝试 SystemRoot explorer exe c Yaya yoyo
  • Python jenkinsapi - 禁用/启用不工作的作业

    我正在尝试使用 禁用作业 詹金萨皮 https jenkinsapi readthedocs io en latest using jenkinsapi html example 3 disable enable a jenkins job
  • 詹金斯没有运行任何作业

    我在尝试解决其他一些问题时成功地破坏了詹金斯 现在 每当我运行作业时 它都会立即失败并出现以下错误 java lang NullPointerException at java util TreeMap putAll TreeMap jav
  • 自动生成/删除詹金斯工作

    我正在寻找一种自动创建一组詹金斯作业的方法 通常在创建新的 git 分支之后 我已经为maven尝试过这个插件 http evgeny goldin com wiki Maven jenkins plugin http evgeny gol
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 如何在 Jenkins 成功构建后触发参数化构建?

    我有三个管道项目 项目 a 项目 b 和项目 c 项目 c 采用一个参数 成功完成项目 a 或项目 b 后 我想使用参数触发项目 c 的构建 我可以在项目 a 和项目 b 中使用管道中的以下代码执行此操作 stage trigger pro
  • Jenkins:从神器部署战争文件

    我们正在使用Jenkins建立 maven 并部署工件 JAR 和 WAR s 到内部工件服务器 快照和版本 对于部署 目前 我们有 Jenkins 作业来打包 war 文件 来自发布 scm 标签 并部署到不同的环境 服务器 我们想要跳过
  • 在 Jenkins Pipeline 的一个步骤中添加多个阶段

    我正在尝试获得一个并行运行 2 个步骤的管道 其中 YAML 如下所示 steps step Step1 stages stage Build steps build a build b build c stage Sniff steps
  • 备份并上传到FTP服务器[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 谁能指导我一个脚本解决方案来备份目录并将其上传到 ftp 服务器 我最初正在寻找批处理脚本 但任何解决
  • 使用批处理文件创建 exe 的快捷方式

    我知道这样的主题已经存在 但我不想使用 VB 脚本 我希望你能在 DOS 中使用命令行创建快捷方式 请发布一些很棒的例子 Thanks AA 如果不调用外部程序 则无法在 bat 文件中创建快捷方式 然而 自 Win2k 以来的每个版本的
  • Artifactory 插件中的“对等未经过身份验证”错误 - Jenkins

    我使用的是 Jenkins 版本 1 566 和 Artifactory 插件版本 2 2 2 我正在它自己的码头容器中运行artifactory 2 66 它以 http 方式运行 但最近我将其更改为 https 现在 如果我将 Jenk
  • 如何从管道作业访问 git 分支名称?

    我有一个 Jenkins Pipeline 作业 配置为签出 git 存储库和特定的本地分支 如何在 Jenkinsfile 中获取本地分支的名称 我尝试加载git詹金斯插件 https wiki jenkins ci org displa
  • 如何从 .bat 运行 .vbs

    创建了一个广泛的批处理脚本程序来处理一些自动文件管理和打印 我需要调用一个 vbs 文件来执行它的 sendkeys 操作 有没有办法在不冻结程序的情况下完成此任务 我试过了START WAIT my vbs并且脚本在进入 vbs 时冻结
  • 如何迭代所有注册表项?

    我正在尝试迭代所有注册表项以查找 包含 并删除 jre1 5 0 14 值 有办法做到吗 下面的代码只是在特定键下找到jre1 5 0 14 我确实想迭代所有的键 顺便说一句 if 子句获取是否等于 jre1 5 0 14 但如果它包含 j
  • 使用 Protobuf-net,我收到有关 List 未知线路类型的异常

    我已经开始将 Unity iOS 游戏转换为使用 Protobuf net 保存状态 看起来一切正常 直到我将此实例变量添加到GameState ProtoMember 10 public List

随机推荐

  • 如何计算采购量与销售量的差额?

    如何使用 Ms Access 数据库计算一次查询中的采购量和销售量之间的差异 例如 我的数据如下所示 ProductId Type Quantity 1 Purchase 24 1 Sale 1 如何在一个查询中获得 24 1 23 的差值
  • 设置超时 Internet Explorer

    我在 MSIE 中有以下 javascript setTimeout myFunction 1000 param 这似乎适用于除 Internet Explorer 之外的所有浏览器 参数只是没有转发到函数 查看调试器 它是未定义的 par
  • 奇怪的通用继承模式

    在一些研究过程中 我遇到了一种使用我以前从未见过的泛型的继承模式 http thwadi blogspot ca 2013 07 using protobuff net with inheritance html http thwadi b
  • 将 cakephp POST 参数插入 URL

    我有下面的表格 其中包含两个复选框来对某些产品进行排序
  • 什么是焊接,JSR-299?

    我发现了很多显示 Weld 代码示例的教程 但没有介绍性概述 您能否推荐一篇介绍性文章 或回答以下问题 Weld 能做什么 给你带来什么 它与 Java EE 6 有什么关系 如何在 Java EE 6 项目中使用它 如果在 Java EE
  • 使用c++ opengl的贝塞尔曲线

    我使用此代码通过单击一个点来绘制贝塞尔曲线 如果我使用编写的静态公式 它会起作用drawBezier函数 它会形成正确的曲线 但是如果我使用写成的广义公式drawBezierGeneralized 最后一点有问题 我究竟做错了什么 incl
  • 将 Hadoop 中的文件获取到 Web 应用程序中

    我是 Hadoop 新手 现在我正在尝试在 eclipse 中做一个应用程序 我想在其中使用 HDFS 中存在的数据 如果我们想用Java连接数据库 我们有JDBC连接 那么 我需要做什么才能直接连接HDFS呢 在 Hadoop 中 首先
  • SQL Server 2016_无法启动镜像

    将SQL Server 2014升级到SQL Server 2016 都是企业版 后 我无法启动镜像 这在 SQL Server 2014 上正常工作 我恢复后 WITH NORECOVERY 镜像数据库 包含我通常运行的主数据库的完整备份
  • 如何强制 Iframe 在标准父框架下运行怪异

    我们有一个父页面必须在 IE9 标准模式下运行 执行 HTML5 命令 下面我们有一个必须在兼容模式 IE7 8 下运行的 iframe 据我了解 在 IE9 中 iframe 继承了父级的文档类型 那是对的吗 这个问题有什么解决办法吗 不
  • 将附加参数传递给 python 回调对象 (win32com.client.dispatchWithEvents)

    我正在使用 win32com 包与 Windows 应用程序交互 应用程序并不重要 简而言之 我想要实现的是订阅更新的表 我已经成功实现了一个回调 该回调接收表更新时返回的数据 但我现在需要的是对收到的数据采取行动 如果我可以使用附加参数实
  • VHDL - iSIM 输出未初始化,不改变状态

    您好 我是一位 Xilinx 新用户 在如何在测试台中编写激励 模拟方面遇到了麻烦 我的输出 Kd 没有给我任何合理的值 并在移动并始终保持在 1 之前的前几个时钟周期给出 u 不确定我是否写了正确的刺激 但希望有人能帮助我 我的VHDL代
  • 空字符串对于 React Link 来说是有效值吗?

    我正在写一个React js http React 20 E2 80 93 20A 20JavaScript 20library 20for 20building 20user 20interfaces 20 20https reactjs
  • 如何在Python中使用将双反斜杠替换为单反斜杠来替换字节字符串

    我想将 Python 中字节字符串的双反斜杠替换为单反斜杠 例如 有一个字节字符串 word b Z xa6 x97 x86j2 x08q r xca xe6m 我需要这个字节字符串 word b Z xa6 x97 x86j2 x08q
  • WPF 类和相应的视觉样式继承

    我已经看过 但显然在与类和样式相关时无法获得正确的语法 我有具有特定行为的控件 我派生出一些来添加额外的行为 现在 我想要一个与每个版本相对应的样式 在最简单的示例中 我将忽略这些类 因为我知道样式与视觉影响具体相关 而不是与功能影响相关
  • 添加 nuget 包源的脚本方式

    我们想要启动一个公司 nuget 包存储库 有没有办法通过命令行添加包源 以便我们可以通过设置或其他方式配置新的包源 我们基本上不想去 工具 选项 包管理器 包源 加号按钮 添加名称和来源 在公司的每台开发人员机器上 包源存储在用户配置文件
  • 如何获取 boto3 集合的大小?

    我一直使用的方法是将Collection转换为List并查询长度 s3 boto3 resource s3 bucket s3 Bucket my bucket size len list bucket objects all 然而 这会强
  • 用颜色条调整子图

    I have made the following visualization I am at loss to figure out how to adjust the size of the third subplot according
  • 防止 $anchorScroll 修改 url

    我在用 anchorScroll https docs angularjs org api ng service 24anchorScroll滚动到 html 元素具有 ID 的页面顶部 brand
  • Spring MVC @RequestMapping 继承

    来自 Struts2 我习惯于声明 Namespace超类上的注释 或package info java 并且继承类随后将获取中的值 Namespace其祖先的注释并将其添加到操作的请求路径之前 我现在正在尝试使用 Spring MVC 做
  • 两个几乎相同的批处理脚本之一中存在语法错误:“)”无法在此处进行语法处理

    我正在尝试设置 Jenkins 服务器来自动构建 Unity 因此 我编写了两个 在我看来 基本相同的批处理脚本 这两个脚本均由 Jenkins 通过Execute Windows batch command步骤使用 Command E u