jenkins Windows批处理命令创建备份文件夹和替换文件夹

thtygnil  于 12个月前  发布在  Jenkins
关注(0)|答案(1)|浏览(158)

我需要备份一个现有的文件夹与日期时间戳,并取代它(删除和重新创建)与文件夹内的新内容。
有没有人有一个脚本来做这件事?
我尝试了以下代码,其中%ApplicationDeploymentFolderPath% = \\servername\foldername

IF EXIST %ApplicationDeploymentFolderPath%\Release (

REM Get current date time
@echo off
For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%b_%%a)
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a%%b)
set backup_folder=%mydate%_%mytime%
MD %ApplicationDeploymentFolderPath%\%backup_folder%

REM Copy current folder to backup folder
Copy %ApplicationDeploymentFolderPath%\Release %ApplicationDeploymentFolderPath%\%backup_folder% 

REM Delete Existing Release folder 
RD %ApplicationDeploymentFolderPath%\Release /S /Q
)

MD %ApplicationDeploymentFolderPath%\Release
ryoqjall

ryoqjall1#

命令date带参数/T输出当前日期,格式由当前用户帐户配置的国家定义。完全相同的日期字符串可以通过引用动态环境变量DATE来访问,例如使用%DATE%
命令time带参数/T输出当前时间,输出格式为当前用户账号配置的国家定义。完全相同的时间字符串可以通过引用动态环境变量TIME来访问,例如使用%TIME%

执行此命令行时会发生什么?

For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%b_%%a)

for分别cmd.exe处理批处理文件开始在后台使用%ComSpec% /c'之间的命令行多一个命令进程。所以在后台执行的是以下与Windows安装在C:\Windows

C:\Windows\System32\cmd.exe /c date /t

用于在后台处理此命令进程的STDOUT命令date的输出由执行批处理文件的FOR相应Windows命令处理器示例捕获。
捕获的行被分成三个子字符串,使用/作为字符串,分配给循环变量abc,它们以相反的顺序连接在一起,下划线作为。
通过将"%DATE%"替换为'date /t',可以更快地完成此任务。在本例中,FOR在执行FOR之前,通过解析此命令行运行cmd.exe来处理扩展的日期字符串。因此,无需在后台再启动一个cmd.exe并捕获其输出,以处理相同的日期字符串,这使得批处理文件的执行速度更快。
'time /t'也是如此,可以用"%TIME%"代替。
但是这两个FOR循环可以通过使用字符串替换来完全优化,例如在What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean?上的answer和区域相关的日期和时间格式是众所周知的,例如通过在命令提示符窗口中运行:

echo %DATE% %TIME%

此命令根据配置的国家/地区在我的计算机上以德语日期/时间格式输出:

24.07.2019 20:15:29,90

在此输出中可以看到,原始代码在我的Windows计算机上无法使用我的帐户,因为日期字符串包含.而不是/,并且时间字符串包含逗号。
因此,最好使用区域独立的解决方案,如在Why does %date% produce a different result in batch file executed as scheduled task?上的回答中详细解释的那样。缺点是执行wmic.exe所需的时间比cmd.exe将日期和时间字符串重新格式化为yyyy_MM_dd_HHmm所需的时间长得多。但是,批处理文件很可能不是每天都经常执行,因此,如果执行以这种格式获取日期/时间需要几毫秒或大约一秒,这并不重要。
在这种情况下,删除整个文件夹并不是真正必要的。它应该足够重命名为:

ren "%ApplicationDeploymentFolderPath%\release" "%backup_folder%"

如果由于未知原因无法使用ren命令,也可以使用move命令。
然而,主要的问题是缺少关于如何以及何时使用delayed expansion的知识。打开一个command prompt,运行set /?并阅读输出帮助解释一个IF和一个FOR示例延迟的环境变量扩展。
这里的问题是,backup_folder在执行使用%backup_folder%引用它的命令行时没有定义,因为所有出现的%variable%都被Windows命令处理器替换,Windows命令处理器已经在执行命令IF之前通过引用的环境变量的当前值解析整个命令块,从这里开始,在顶部的IF条件下使用(
因此,在现有发布文件夹上执行的是:

set backup_folder=
MD \\servername\foldername\

REM Copy current folder to backup folder
Copy \\servername\foldername\Release \\servername\foldername\ 

REM Delete Existing Release folder 
RD \\servername\foldername\Release /S /Q

这可以通过debugging the batch file看到。
标签:How does the Windows Command Interpreter (CMD.EXE) parse scripts?
这里的解决方案是通过更改第一个IF条件来避免命令块。
快速区域相关解决方案:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ApplicationDeploymentFolderPath=\\servername\foldername"

if not exist "%ApplicationDeploymentFolderPath%\Release\" goto CreateFolder

ren "%ApplicationDeploymentFolderPath%\Release" "%DATE:~-4%_%DATE:~-7,2%_%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%"

:CreateFolder
md "%ApplicationDeploymentFolderPath%\Release"
endlocal

慢区域独立解:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ApplicationDeploymentFolderPath=\\servername\foldername"

if not exist "%ApplicationDeploymentFolderPath%\Release\" goto CreateFolder

for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "BackupDateTime=%%I"
set "BackupDateTime=%BackupDateTime:~0,4%_%BackupDateTime:~4,2%_%BackupDateTime:~6,2%_%BackupDateTime:~8,4%"
ren "%ApplicationDeploymentFolderPath%\Release" "%BackupDateTime%"

:CreateFolder
md "%ApplicationDeploymentFolderPath%\Release"
endlocal

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读显示的每个命令的帮助页。

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • ren /?
  • set /?
  • setlocal /?
  • wmic /?
  • wmic os /?
  • wmic os get /?
  • wmic os get localdatetime /?

相关问题