一尘不染

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

jenkins

我需要备份带有日期时间戳的现有文件夹,并将其替换(删除并重新创建)为文件夹内的新内容。

有人有脚本可以做到这一点吗?

我尝试了以下代码,其中 %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

阅读 428

收藏
2020-07-25

共1个答案

一尘不染

带参数的 命令 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

的输出 命令 date到手柄 STDOUT 在背景该命令处理的被捕获 FOR 分别Windows命令处理器实例执行批处理文件。

捕获的行使用/分配给循环变量的字符串定界符分成三个子字符串abc以下划线作为定界符以相反的顺序串联在一起。

替换'date /t'为可以更快地完成此任务"%DATE%"。在这种情况下, FOR* 处理在执行 FOR
之前已经在解析此命令行上运行的扩展的日期 字符串 。因此,无需再在后台开始并捕获其输出来处理相同的日期 字符串
,从而使批处理文件的执行速度更快。cmd.exe
cmd.exe ***

'time /t'可以替换为的情况也是如此"%TIME%"

但是可以通过使用字符串替换来完全优化两个 FOR 循环,例如通过回答%date:〜-4,4 %% date:〜-10,2 %%
date:〜-7,2% _%time:〜0.2 %%
time:〜3.2%是什么意思?
依赖于区域和日期和时间的格式是众所周知的,例如通过在命令提示符窗口中运行:

echo %DATE% %TIME%

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

24.07.2019 20:15:29,90

在此输出中可以看到,由于日期字符串包含.而不是/时间字符串包含逗号,因此原始代码无法在我的Windows计算机上使用我的帐户运行。

最好使用区域无关的解决方案,如有关%date%为什么在按计划任务执行的批处理文件中产生不同结果的答案中非常详细地解释的那样。缺点是执行wmic.exe所需的时间比cmd.exe重新格式化日期和时间字符串所需的时间长得多yyyy_MM_dd_HHmm。但是,批处理文件很可能不是每天执行一次,因此执行这种格式的日期/时间花费几毫秒或一秒钟的时间并不重要。

在这种情况下,实际上并不需要复制整个文件夹。用以下命令重命名就足够了:

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

move如果ren由于未知原因无法使用命令,则也可以使用该命令。

但是,主要问题是缺少有关如何以及何时使用延迟扩展的知识。打开命令提示符,运行set /?并阅读有关 IFFOR 示例的解释环境变量扩展的输出帮助。

这里的问题是,backup_folder是不是与执行命令行引用它定义的%backup_folder%,因为所有出现的%variable%由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

这可以通过调试批处理文件看到。

解决方案是通过更改第一个 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 /?
2020-07-25