为什么批处理文件执行仅在 Jenkins 中失败,并显示压缩的 .rar 文件不存在的错误消息?

Why does batch file execution fail ONLY IN Jenkins with error message that compressed .rar file doesn't exist?

我创建了简单的批处理文件,用于备份我的 Jenkins 目录。一切正常,但是一旦我用“Execute Windows batch command”设置我的build,批处理文件就会失败说“文件已经存在,或者无法找到(德语的松散翻译)。但是,运行 具有用户交互的本地脚本工作正常!

@echo off &color 1f && Title [Backup for Jenkins]

REM Path for Winrar
set path="C:\Program Files\WinRAR\";%path%

REM German Date-Format
set gerDate=%date:~0,2%-%date:~3,2%-%date:~6,4%

REM Winrar Backup
REM Base-Folder skipped
rar a -u -ep1 -r -agHH-MM -xC:\[Path for 1st skipped folder]\ -xC:\[Path for 2nd skipped folder] Jenkins_%gerDate%_.zip C:\[Path to compress all the following files]\*.*
color 2f & Title [Backup successful]

echo.
echo Move into different folder
echo.
move C:\[Path to the generated .zip file]\Jenkins*.zip C:\[Path to destination folder - network drive]\
echo.
echo Backup completed on%Date% %Time% 
echo.
pause

我注意到我的脚本临时存储在 C:\Users\[USER]\AppData\Local\Temp 中,因为脚本必须移动压缩的 .使用 cmd 命令 "move" 将 rar 放入不同的文件夹,这可能会导致我的问题...无论哪种方式,即使在 Temp 文件夹中也不会生成我的 .rar,因此情况也可能并非如此。

第一个错误在行中:

set path="C:\Program Files\WinRAR\";%path%

正确的是

set "path=C:\Program Files\WinRAR;%path%"

分配给环境变量 PATH 的文件夹路径列表中的文件夹路径不应用双引号引起来,除非文件夹路径包含一个或多个分号。文件夹路径末尾也应该没有反斜杠。

然而,这一行并不是真正的问题,当然也根本不需要,因为它可以在下面的批处理文件代码中看到。

另请参阅 Why is no string output with 'echo %var%' after using 'set var = text' on command line? 以了解为什么在参数字符串末尾留下一个 " 和另一个 " 的解释。


第二个错误是整行:

set gerDate=%date:~0,2%-%date:~3,2%-%date:~6,4%

这一行很可能是真正的问题。

我想您的用户帐户的国家/地区德国配置为日期格式 dd.MM.yyyy,这意味着 25.09.2018

但 Jenkins 作为系统帐户服务运行,很可能使用不同的日期格式,例如英语 U.S。导致日期字符串 Tue, 09/25/2018.

所以 getDateTu-, -9/25 而不是 25-09-2018 并且 / 被解释为像 \ 这样的目录分隔符,它是 [= 上的真正目录分隔符125=].

因此 Jenkins_%gerDate%_.zip 由 Jenkins 执行 Jenkins_Tu-, -9/25_.zip 并且 Rar.exe 在当前目录中找不到子目录 Jenkins_Tu-, -9 来创建文件 25_HH-mm.zip 在此目录中。

另请参阅:


第三个错误是使用 Rar.exe 指定文件扩展名 .zip。控制台版本 Rar.exe 的手册是 WinRAR 的程序文件文件夹中的文本文件 Rar.txt。可以在该文本文件的顶部看到 Rar.exe 仅支持 RAR 存档文件格式。所以所有创建的档案都是 RAR 而不是 ZIP 档案,尽管文件扩展名是 .zip.


有趣的是开关 -agHH-MM 一起使用,尽管 Rar.exe 不仅支持附加当前小时和分钟,还支持以自定义格式附加当前日期使用 -ag 在文件扩展名之前归档文件名。

所以根本不需要set gerDate=...命令行,使下面的批处理代码独立于所用帐户的区域设置。


接下来 Rar.exe 的手册描述 *.* 不像 * 那样被解释为 Windows 命令处理器。 *.* 意味着要添加到存档的文件必须在其文件名中有一个点,否则 Rar.exe 将忽略该文件。看起来应该将目录递归添加到存档中,同时更新存档中的现有文件并排除两个目录。出于这个原因,在要存档的文件夹的文件夹路径末尾应使用 * 或不使用通配符,因为 * 是不使用通配符的默认值。

另请参阅 Simply compress 1 folder in batch with WinRAR command line?,了解为什么下面的批处理文件代码中的指定文件夹路径以反斜杠结尾。


Rar.exe 可以在任何现有目录中创建存档文件。无需在当前目录中创建它,然后将文件移动到目标目录。


手册 Rar.txt 在底部附近包含了可能的退出代码。

因此可以检查 if errorlevel 1 是否发生任何错误,这意味着退出代码是否 大于或等于 1,如命令 [=110] 的帮助所述=]IF 在命令提示符 运行 上输出 window if /?.

if not errorlevel 1 是相反的,即退出代码 低于 1 这意味着等于 0 因为 Rar.exe 永远不会以负值退出几乎所有应用程序和命令的价值。


所以让我们将所有这些信息放在一个新的批处理文件中:

@echo off
color 1f
title [Backup for Jenkins]

rem WinRAR backup, base folder skipped
"C:\Program Files\WinRAR\rar.exe" u -agYYYY-MM-DD_HH-MM -ep1 -r -inul -x"C:\[Path for 1st skipped folder]\" -x"C:\[Path for 2nd skipped folder]" "C:\[Path to destination folder - network drive]\Jenkins_.rar" "C:\[Path to compress all the following files]\"

if not errorlevel 1 color 2f & title [Backup successful]
echo Backup completed on %DATE% %TIME%
echo/
pause

我还添加了 -inul 禁用所有输出到控制台并隐含地导致从不提示用户喜欢另外使用开关 -y 否则应该在这里使用例如使用 -icdpq 而不是 -inul 来获取 Jenkins 捕获的输出错误消息,但没有其他状态信息。