der*_*ugo 5 batch-file unity-game-engine jenkins
我正在尝试为自动 Unity 构建设置 Jenkins 服务器。
因此,我编写了两个(在我看来)基本相同的批处理脚本。
这两个脚本都由 Jenkins 通过一个Execute Windows batch command步骤作为构建步骤运行
命令: E:\unityImport.bat
然后Execute Windows batch command第二步使用
命令: E:\unityBuild.bat
它们都有相同的开头,因为我需要收集一些文件路径,特别是项目的统一版本。所以在这两个脚本中,我使用完全相同的解析和字符串拆分项目版本的方式。它们之间唯一不同的是,第一个启动 Unity 并将专用的unitypackage(保存在下一步中执行的方法)导入项目,而第二个再次启动 Unity 以执行实际构建(不幸的是它没有不能一次性工作...... Unity 似乎尝试在unitypackage导入之前执行该方法)。
然而,第二个脚本总是失败并出现语法错误
")" 不能在这里进行语法处理。
我试图实现的是
读出文件的内容 %WORKSPACE%\ProjectSettings\ProjectVersion.txt
SET /p TEST=<%WORKSPACE%\ProjectSettings\ProjectVersion.txt
Run Code Online (Sandbox Code Playgroud)
的内容%TEST%通常看起来像例如
m_EditorVersion: 2019.3.4f1
Run Code Online (Sandbox Code Playgroud)
和ECHO. ProjectVersion.txt = %TEST%看起来像
ProjectVersion.txt = m_EditorVersion: 2019.3.4f1
Run Code Online (Sandbox Code Playgroud)字符串拆分以便只取包含版本号的最后一部分
for %%x in (%TEST::= %) do (
SET "VALUE=%%x"
SET "UNITY_VERSION=!VALUE:~0,-2!"
)
Run Code Online (Sandbox Code Playgroud)
所以%UNITY_VERSION%通常包含例如2019.3.4. 我不会拆分更多,因为也有两位数的 Unity 版本,例如2018.4.18
字符串拆分.,以便仅获取主要版本号
for /f "tokens=1,2 delims=." %%a in ("%UNITY_VERSION%") do (
SET "A=%%a"
SET "B=%%b"
)
SET "UNITY_VERSION=%A%.%B%"
Run Code Online (Sandbox Code Playgroud)
这导致%UNITY_VERSION%例如2019.3
最后搜索所有已安装的 Unity 版本是否存在所需的版本
set "UNITY_FOLDER="
for /f "delims=" %%a in ('dir /b E:\Unity\%UNITY_VERSION%*') do (
set "UNITY_FOLDER=%%a"
)
Run Code Online (Sandbox Code Playgroud)
在此之后,我们要么找到了给定版本的有效 Unity 安装文件夹。
所以这里是脚本。
导入(这按预期工作)
@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
Run Code Online (Sandbox Code Playgroud)
构建(这会失败并出现语法错误,我将用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%
...
Run Code Online (Sandbox Code Playgroud)
我认为其余的并不重要,因为正如我在控制台中看到的那样,它已经在例如之后中断了
项目版本.txt = 2019.3.4f1
")" 不能在这里进行语法处理。
有没有人看到这个错误,或者 Jenkins 是否有一些东西使第二个脚本失败并出现语法错误,即使据我所知它们基本相同?
Mof*_*ofi 13
代码有多个小问题,我在我对批处理文件的建议下面一个接一个地解释了这些问题。
使用以下代码可以更有效地完成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
Run Code Online (Sandbox Code Playgroud)
该批处理文件首先使用命令SETLOCAL设置该批处理文件所需的执行环境。
WORKSPACE接下来通过批处理文件验证环境变量的存在。这个环境变量应该由 Jenkins 在这个批处理文件之外定义。缺少此重要环境变量的定义时会输出错误消息。
然后检查文本文件是否存在,如果不存在则打印错误消息并以退出代码 1 退出批处理文件。
如果在批处理文件之外偶然定义了这两个环境变量UNITY_FOLDER和 ,UNITY_VERSION则会被删除。
接下来处理文本文件,它应该只包含一个包含感兴趣数据的非空行。否则,如果m_EditorVersion:在执行其他命令之前相等,则需要更改代码以评估第一个子字符串。
带有选项的FOR/F将"默认包含的集合解释为要处理的字符串。但在这种情况下,字符串 in"应该被解释为文件的全限定文件名,其内容应该由FOR逐行处理。因此,该选项usebackq用于获取所需的文件内容处理行为。
FOR在处理文件内容时总是忽略空行。因此,文本文件顶部是否包含一个或多个空行并不重要。
FOR默认情况下使用普通空格和水平制表符作为字符串分隔符将一行拆分为子字符串。如果在删除所有前导空格/制表符后,第一个空格/制表符分隔的字符串以分号作为默认行尾字符开头,则该行也将被FOR像空行一样忽略。最后,将仅将第一个空格/制表符分隔的字符串分配给指定的循环变量I。
这里不需要这种默认的行处理行为,因为仅仅m_EditorVersion:分配给指定的循环变量I是不够的。出于这个原因,该选项delims=. 用于在点和空格上分割线。该选项tokens=2-4通知FOR2019应将第二个空格/点分隔子字符串分配给循环变量I,将第三个空格/点分隔子字符串3分配给下一个循环变量J,即ASCII 表中的下一个字符,第四个空格/点分隔子字符串4f1分配给 next 但一个循环变量K。
指定这里重要delims=. 的选项参数字符串以空格字符作为,因为空格字符的最后一个字符的一端,否则解释为一个选项分隔符忽略像之间的空间usebackq与tokens=2-4和之间的空间tokens=2-4和delims=. 。事实上,也可以编写不带空格的选项,例如"usebackqtokens=2-4delims=. ",但这会使带有选项的参数字符串难以阅读。
默认的行尾定义eol=;可以保留在这里,因为带有统一版本的行在ProjectVersion.txt0 或多个空格/点之后没有分号,因此永远不会被忽略。
FOR运行命令块中的命令,至少在行中找到分配给循环变量的第二个空格/点分隔的字符串I,即一个非空字符串分配给指定的循环变量I。但是,只有当统一版本的所有三个部分都由FOR确定并分配给循环变量时I,才应该执行命令,J和K。因此,进行简单的字符串比较以验证循环变量值引用%%~K不会扩展为空字符串,因为这意味着没有从文件中读取足够的统一版本部分。
我不知道f1编辑器版本的末尾是什么意思。因此,另一个带有选项的FOR/F用于使用字符(小写十六进制字符)作为字符串分隔符将字符串 4f1(没有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"
)
)
Run Code Online (Sandbox Code Playgroud)
FOR带有选项/D和包含*(或?)的集合会导致在指定目录中搜索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 存储目录条目在其文件分配表中未排序。
注意:如果根据相关代码看起来并不真正需要第三个编辑器版本号,则也可以使用:
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"
)
)
Run Code Online (Sandbox Code Playgroud)
如果代码可以成功确定统一版本并找到匹配的统一文件夹,则会进行两项额外检查。
echo批处理文件底部的命令行仅用于验证运行此批处理文件的结果,WORKSPACE并在命令提示符窗口中的批处理文件之外定义,一切都按预期工作。
没有必要使工作区目录成为批处理文件末尾的当前目录,但我添加了代码来验证是否将当前目录更改为工作区目录真的成功完成。
在命令提示符下 运行的帮助输出cmd /?解释了最后一页的最后一段,包含空格或这些字符之一的文件/文件夹参数字符串&()[]{}^=;!'+,`~需要将双引号括起来。因此,建议始终将文件/文件夹名称不包含或包含路径 in 括起来",尤其是在由环境变量动态定义或从文件系统读取的一个或多个部分上。
所以不好的是以下命令行:
cd %WORKSPACE%
IF NOT EXIST %WORKSPACE%\ProjectSettings\ProjectVersion.txt
SET /p TEST=<%WORKSPACE%\ProjectSettings\ProjectVersion.txt
Run Code Online (Sandbox Code Playgroud)
最好使用:
cd "%WORKSPACE%"
IF NOT EXIST "%WORKSPACE%\ProjectSettings\ProjectVersion.txt"
SET /p TEST=<"%WORKSPACE%\ProjectSettings\ProjectVersion.txt"
Run Code Online (Sandbox Code Playgroud)
可以在运行时的简短帮助输出中读取cd /?命令CD不会将空格字符解释为参数分隔符,就像 Windows 命令处理器的大多数其他内部命令cmd.exe或目录%SystemRoot%\System32中的可执行文件的情况一样,这些命令默认安装并且也属于根据 Microsoft的Windows 命令。但是,"如果目录路径偶然包含一个&符号,则更改当前目录会失败,因为在执行CD之前,&双引号参数字符串已经被解释cmd.exe为AND运算符,例如在我对具有多个命令的单行的回答中所述。
最好"在每个可能包含空格或&()[]{}^=;!'+,`~重定向运算符的参数字符串上使用环绕,这些运算符<>|应该由 Windows 命令处理器解释为参数字符串的文字字符。好吧,方括号对于 Windows 命令处理器不再具有特殊含义。[]由于历史原因COMMAND.COM,从 MS-DOS 的第一个版本开始,它们就在列表中,并不总是将它们解释为文字字符。
Windows 命令处理器主要设计用于
命令IF on running的帮助输出if /?显示在第一页顶部,在条件为真时执行的命令与命令IF位于同一行的一般语法。命令FOR运行时的帮助输出for /?显示在第一页顶部的一般语法,在每个循环迭代中执行的命令与命令FOR位于同一行。因此,这种推荐的语法应该用于IF条件和只需要执行一个命令的FOR循环。
让我们看看 Windows 命令处理器如何解释以下IF条件,环境变量WORKSPACE定义为C:\Temp:
IF NOT EXIST %WORKSPACE%\ProjectSettings\ProjectVersion.txt (
EXIT 1
)
Run Code Online (Sandbox Code Playgroud)
只有这三行的批处理文件会导致执行:
IF NOT EXIST C:\Temp\ProjectSettings\ProjectVersion.txt (EXIT 1 )
Run Code Online (Sandbox Code Playgroud)
所以Windows命令处理器检测到有一个以 开头的命令块(,从批处理文件中读取多行直到匹配),发现命令块只有一个命令行,并将这三行合并为一个命令行原因。
因此,通过写入批处理文件可以加快批处理文件的处理速度:
IF NOT EXIST "%WORKSPACE%\ProjectSettings\ProjectVersion.txt" EXIT /B 1
Run Code Online (Sandbox Code Playgroud)
然后需要更少的 CPU 指令来执行cmd.exe。
IF NOT EXIST "C:\Temp\ProjectSettings\ProjectVersion.txt" EXIT /B 1
Run Code Online (Sandbox Code Playgroud)
但是,命令块的使用总是可以使批处理文件的代码更具可读性。
如果可以避免对批处理文件进行大量文件打开、读取、关闭操作,有时会对批处理文件产生巨大影响,那么将批处理文件的整个代码或其中经常执行的部分代码放入一个命令块甚至可能很有用总执行时间如为什么 GOTO 循环比 FOR 循环慢得多并且另外取决于电源?
另请参阅Windows 命令解释器 (CMD.EXE) 如何解析脚本?
DosTips 论坛主题ECHO。FAILS to give text or empty line - 相反,使用 ECHO/解释ECHO.可能无法输出文本或空行。的使用ECHO/是更好,如果下一个字符不是?,最好的是ECHO(。
如果保证在like on之后有文本要输出,则将命令ECHO与要输出的字符串分隔开的字符可以是标准参数分隔符空间。ECHO ECHO ProjectVersion.txt = %TEST%
ECHO/ 输出空行就好。
ECHO( 如果下一个环境变量引用或循环变量引用在定义环境变量之前无法确定,或者循环变量存在一个不以问号开头的非空字符串,则最好。
可以使用从文本文件中set /P读取第一行并将此行分配给环境变量,如下所示:
SET /p TEST=<%WORKSPACE%\ProjectSettings\ProjectVersion.txt
Run Code Online (Sandbox Code Playgroud)
但是文本文件必须具有要分配给文件顶部的环境变量的文本。文本文件顶部的空行导致没有为环境变量赋值,这意味着如果环境变量TEST已经定义,它的值根本没有改变,如果环境变量TEST之前没有定义,它仍然没有在执行SET后定义。
最好使用带有选项的FOR命令/F来处理文本文件的内容。
命令EXIT退出正在处理批处理文件的 Windows 命令进程。它总是有效,但仍然应该避免在大多数批处理文件中使用没有选项的EXIT/B。
在其上批文件EXIT没有/B没有或退出代码被执行cmd.exe的结果cmd.exe总是终止本身,甚至对cmd.exe正在启动隐性或显性与选项/K保留命令过程完成一个命令,命令行或批处理文件执行之后运行,独立于批处理文件调用层次结构。
因此,带有EXIT选项的批处理文件/B很难调试,因为即使在命令提示符窗口中运行批处理文件,而不是双击它以查看错误消息,命令进程和控制台窗口也会在cmd.exe到达命令时关闭与EXIT行。
设计良好的批处理文件不依赖于在批处理文件之外定义的执行环境。这两个批处理文件使用的命令具有仅在启用命令扩展时可用的功能。命令扩展默认启用,延迟环境变量扩展默认禁用,但最好是批处理文件定义自己的执行环境并在退出之前恢复先前的执行环境。这可确保批处理文件始终按设计工作,即使调用此批处理文件的另一个批处理文件设置了不同的执行环境。
所以在@echo off确保关闭ECHO模式之后,下一个命令行应该是:
setlocal EnableExtensions DisableDelayedExpansion
Run Code Online (Sandbox Code Playgroud)
那么批处理文件肯定是在预期的环境中执行的。该命令endlocal应位于批处理文件的末尾以恢复初始执行环境。但是Windows命令处理器endlocal在退出批处理文件处理之前隐式运行,对于每个执行的批处理文件,在退出批处理文件处理之前setlocal没有执行匹配endlocal。
执行setlocal /?和endlocal /?导致显示这两个命令的帮助。在此答案中可以找到更好的解释,其中包含有关命令SETLOCAL和ENDLOCAL 的更多详细信息。
的使用setlocal在批处理文件的顶部设置所需的执行环境,并endlocal在批处理文件的底部,以恢复初始执行环境必须明智地将刚做完批处理文件的情况下,应通过环境变量结果返回到初始执行环境,比如调用当前执行的批处理文件的父批处理文件。
ADFNPSTXZadfnpstxz作为循环变量运行时FOR输出命令的帮助for /?描述了可用于引用循环变量值的修饰符。
Run Code Online (Sandbox Code Playgroud)%~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可以组合修饰符以获得复合结果:
Run Code Online (Sandbox Code Playgroud)%~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 = ?
Run Code Online (Sandbox Code Playgroud)
直接在命令提示符窗口中执行的相同示例:
for %x in ("1" 2,3;4) do @echo %~xx5 = ?
Run Code Online (Sandbox Code Playgroud)
输出通常是(并非总是):
5 = ?
5 = ?
5 = ?
5 = ?
Run Code Online (Sandbox Code Playgroud)
但是输出I在批处理文件中使用更有意义:
for %%I in ("1" 2,3;4) do echo %%~Ix5 = ?
Run Code Online (Sandbox Code Playgroud)
直接在命令提示符窗口中执行的相同命令行:
for %I in ("1" 2,3;4) do @echo %~Ix5 = ?
Run Code Online (Sandbox Code Playgroud)
在这种情况下,输出总是:
1x5 = ?
2x5 = ?
3x5 = ?
4x5 = ?
Run Code Online (Sandbox Code Playgroud)
所以不可能ADFNPSTXZadfnpstxz用作循环变量,如果
%~(命令提示符窗口) 或%%~(批处理文件) 和所以在命令提示符窗口中工作正常是:
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.
Run Code Online (Sandbox Code Playgroud)
但是,使用可用于引用分配给带有修饰符的循环变量的字符串值的字母时,可读性不好。
在命令提示符窗口中使用的可读性示例:
for %i in (*) do @echo %~si
for %f in (*) do @echo %~sf
for %i in (*) do @echo %~sni
for %f in (*) do @echo %~snf
Run Code Online (Sandbox Code Playgroud)
在这种情况下i,f两者都工作并且输出是相同的,独立于ior 的使用f。但是更容易看到修饰符(s和n)是什么以及循环变量是 usingi而不是f循环变量。
#如果不使用FOR和选项/F将多个子字符串分配给多个循环变量,则也可以使用其他 ASCII 字符,而不是对 Windows 命令处理器没有特殊意义的字母作为循环变量。
让我们看看使用以下代码真正发生了什么:
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
Run Code Online (Sandbox Code Playgroud)
在解析FOR命令行及其命令块时,字符串替换%TEST::= %导致将每个冒号替换为分配给环境变量的字符串中的空格。所以字符串TEST
m_EditorVersion: 2019.3.4f1
Run Code Online (Sandbox Code Playgroud)
变成
m_EditorVersion 2019.3.4f1
Run Code Online (Sandbox Code Playgroud)
下一个 Windows 命令处理器将m_EditorVersion和之间的两个空格替换为2019.3.4f1一个空格作为清理。所以要处理的集合for最终是在解析和预处理命令行for及其命令块之后:
m_EditorVersion 2019.3.4f1
Run Code Online (Sandbox Code Playgroud)
这个集合既不包含*也不包含?。出于这个原因,命令FOR将集合解释为两个简单的空格分隔字符串,以x一个接一个地分配给指定的循环变量,并对这两个字符串执行命令块中的命令两次。
在第一次迭代时m_EditorVersion分配给环境变量VALUE和m_EditorVersi环境变量UNITY_VERSION。这并不是真正想要的,但是FOR再次运行这两个命令,这次2019.3.4f1分配给循环变量x。所以在第二个循环迭代中2019.3.4f1被分配给环境变量VALUE和2019.3.4环境变量UNITY_VERSION。
UNITY_VERSION 最后用想要的字符串定义,但可以做得更好,如本答案顶部所示和解释。
我不太清楚为什么for命令行会导致错误消息:
")" 不能在这里进行语法处理。
对于分配给环境变量的FOR循环,这种情况永远不会发生。m_EditorVersion: 2019.3.4f1TEST
要么TEST是用字符串定义的,导致执行第二个批处理文件时出现语法错误,尽管根据描述不应该是这种情况,或者存在(解释为命令块开头的问题并且 Windows 命令处理器无法找到)标记命令块结束的匹配项。
| 归档时间: |
|
| 查看次数: |
481 次 |
| 最近记录: |