I've created simple batch file, that backs up my Jenkins directory. Everything is working without a hitch, but once I set up my build with "Execute Windows batch command" the batch file will fail saying "File already exist, or couldn't be found (loose translation from German). However, running the script locally with user-interaction is working just fine!
@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
I've noticed that my script is being temporary stored in C:\Users\[USER]\AppData\Local\Temp and since the script has to move the compressed .rar with cmd's command "move" into different folder, it might be causing my problems... Either way, my .rar is not generated even within Temp folder, so that might not be the case as well.
The first mistake is in line:
set path="C:\Program Files\WinRAR\";%path%
Correct would be
set "path=C:\Program Files\WinRAR;%path%"
A folder path in semicolon separated list of folder paths assigned to environment variable PATH
should not be enclosed in double quotes except the folder path contains one or more semicolons. A folder path should be also without backslash at end.
However, this line is not really the problem and of course is also not needed at all as it can be seen on the batch file code below.
See also Why is no string output with 'echo %var%' after using 'set var = text' on command line? for an explanation why there is one "
left the environment variable name and one more "
at end of the argument string.
The second mistake is the entire line:
set gerDate=%date:~0,2%-%date:~3,2%-%date:~6,4%
This line is most likely the real problem.
I suppose that for your user account the country Germany is configured resulting in the date format dd.MM.yyyy
which means 25.09.2018
.
But Jenkins runs as service with system account which is most likely using a different date format like for example English U.S. resulting in date string Tue, 09/25/2018
.
So getDate
is Tu-, -9/25
instead of 25-09-2018
and /
is interpreted as directory separator like \
which is the real directory separator on Windows.
For that reason Jenkins_%gerDate%_.zip
becomes on execution by Jenkins Jenkins_Tu-, -9/25_.zip
and Rar.exe
can't find in current directory the subdirectory Jenkins_Tu-, -9
to create the file 25_HH-mm.zip
in this directory.
See also: Why does %date% produce a different result in batch file executed as scheduled task?
The third mistake is using Rar.exe
with specifying file extension .zip
. The manual for console version Rar.exe
is the text file Rar.txt
in program files folder of WinRAR. It can be read at top of this text file that Rar.exe
supports only RAR
archive file format. So all created archives are RAR and not ZIP archives although the file extension is .zip
.
It is interesting to see that switch -ag
is used with HH-MM
although Rar.exe
supports also appending not only current hour and minute, but also current date in a customizable format with using -ag
to archive file name before file extension.
So the set gerDate=...
command line is not needed at all making the batch code below independent on region setting of used account.
Next the manual of Rar.exe
describes that *.*
is not interpreted like *
as Windows command processor does. *.*
means really the file to add to the archive must have a dot in its file name or Rar.exe
ignores the file. It looks like a directory should be recursively added to an archive with updating existing files in archive and with excluding two directories. For that reason just *
or no wildcard at end of folder path of the folder to archive should be used as *
is the default on no wildcard used.
See also Simply compress 1 folder in batch with WinRAR command line? for an explanation why the specified folder path in batch file code below ends with a backslash.
Rar.exe
can create the archive file in any existing directory. There is no need to create it in current directory and next move the file to destination directory.
The manual Rar.txt
contains near bottom the possible exit codes.
So it is possible to check if any error occurred with if errorlevel 1
which means if exit code is greater or equal 1 as described by help of command IF output on running in a command prompt window if /?
.
if not errorlevel 1
is the opposite, i.e. exit code is lower than 1 which means equal 0
as Rar.exe
never exits with a negative value as nearly all applications and commands.
So let us put all these information together to a new batch file:
@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
I added also -inul
which disables all output to console and implicitly results in never prompting the user like on using additionally the switch -y
which otherwise should be used here for example on using -icdpq
instead of -inul
to get output error messages which Jenkins captures, but no other status information.