batch-file - 为什么批处理文件执行仅在 Jenkins 中失败,并显示压缩的 .rar 文件不存在的错误消息?
问题描述
我创建了简单的批处理文件,用于备份我的 Jenkins 目录。一切都顺利进行,但是一旦我使用“执行 Windows 批处理命令”设置我的构建,批处理文件将失败,说“文件已经存在,或找不到(来自德语的松散翻译)。但是,运行脚本在本地与用户交互工作得很好!
@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
不应用双引号引起来,除非文件夹路径包含一个或多个分号。文件夹路径末尾也应该没有反斜杠。
然而,这一行并不是真正的问题,当然也根本不需要,因为它可以在下面的批处理文件代码中看到。
另请参阅为什么在命令行上使用 'set var = text' 后没有带有 'echo %var%' 的字符串输出?解释为什么在参数字符串的末尾有一个"
环境变量名和一个。"
第二个错误是整行:
set gerDate=%date:~0,2%-%date:~3,2%-%date:~6,4%
这条线很可能是真正的问题。
我想对于您的用户帐户,德国配置的国家/地区会导致日期格式dd.MM.yyyy
,这意味着25.09.2018
。
但是 Jenkins 使用系统帐户作为服务运行,该帐户很可能使用不同的日期格式,例如 English US 导致日期字符串Tue, 09/25/2018
。
So getDate
isTu-, -9/25
而不是25-09-2018
并被/
解释为目录分隔符,就像\
Windows 上真正的目录分隔符一样。
出于这个原因Jenkins_%gerDate%_.zip
,詹金斯执行Jenkins_Tu-, -9/25_.zip
时Rar.exe
无法在当前目录中找到在该目录Jenkins_Tu-, -9
中创建文件的子目录25_HH-mm.zip
。
另请参阅:为什么 %date% 在作为计划任务执行的批处理文件中会产生不同的结果?
第三个错误是使用Rar.exe
with 指定文件扩展名.zip
。控制台版本的手册是WinRAR程序文件夹中Rar.exe
的文本文件。可以在此仅支持存档文件格式的文本文件顶部读取它。因此,所有创建的档案都是 RAR 而不是 ZIP 档案,尽管文件扩展名为.Rar.txt
Rar.exe
RAR
.zip
有趣的是,开关-ag
与使用一起使用HH-MM
虽然Rar.exe
还支持不仅支持当前小时和分钟,还支持以可自定义格式附加当前日期,并-ag
在文件扩展名之前使用存档文件名。
因此,set gerDate=...
根本不需要命令行,使下面的批处理代码独立于所用帐户的区域设置。
接下来Rar.exe
描述的手册*.*
不像*
Windows 命令处理器那样解释。*.*
意味着要添加到存档的文件必须在其文件名中包含一个点或Rar.exe
忽略该文件。看起来应该将目录递归添加到存档中,并更新存档中的现有文件并排除两个目录。因此,*
在要归档的文件夹的文件夹路径末尾只使用或不使用通配符,就像不使用通配符*
的默认设置一样。
另请参阅使用 WinRAR 命令行批量压缩 1 个文件夹?解释为什么下面的批处理文件代码中的指定文件夹路径以反斜杠结尾。
Rar.exe
可以在任何现有目录中创建存档文件。无需在当前目录中创建它,然后将文件移动到目标目录。
该手册Rar.txt
在底部附近包含可能的退出代码。
因此,可以检查是否发生任何错误,if errorlevel 1
这意味着退出代码是否大于或等于 1 ,如在命令提示符窗口中运行时命令IF输出的帮助所述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 捕获的输出错误消息,但没有其他状态信息。
推荐阅读
- mongodb - 如何使用 MongoDB API 从 Cosmos DB 获取 N 个随机文档?
- python - requests.get(url) 没有返回这个特定的 url
- python - 我想知道如何在 python-vlc 中编写音频播放回调
- javascript - React JS 将数据或子组件传递给父组件
- azure-timeseries-insights - 从原始数据构建累积变量/聚合
- bash - 为什么 bash 后增量运算符设置非零结果代码?
- laravel-8 - request()->validate() 在 n laravel 8 左右第二次不起作用
- excel - 分块和超越 Laravel
- python - Matplotlib 反转图例顺序(X 轴),但保持图形方向相同
- javascript - 第 4:13 行:'React' 未定义 no-undef