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

问题描述 投票:0回答:1

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

有人有执行此操作的脚本吗?

我尝试了以下代码,其中

%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
windows batch-file jenkins
1个回答
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

在后台处理此命令进程的 STDOUT

command
date 的输出由执行批处理文件的 FOR 分别捕获。

使用

/
作为分配给循环变量
a
b
c
的字符串分隔符,将捕获的行分成三个子字符串,这些子字符串以相反的顺序连接在一起,并使用下划线作为分隔符。

通过将

'date /t'
替换为
"%DATE%"
,可以更快地完成此任务。在这种情况下,FOR处理日期string,该日期是通过在执行
FOR
之前在解析此命令行时运行cmd.exe而扩展的。因此,无需在后台启动另一个
cmd.exe
并捕获其输出只是为了处理相同的日期 string,这使得批处理文件执行速度更快一些。

'time /t'
也是如此,可以用
"%TIME%"
代替。

但是两个 FOR 循环可以通过使用字符串替换来完全优化,例如通过回答 What does %date:~-4,4%%date:~-10,2%%date:~- 7,2%_%时间:~0,2%%时间:~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

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

另请参阅:Windows 命令解释器 (CMD.EXE) 如何解析脚本?

解决方案是通过更改第一个 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 /?
© www.soinside.com 2019 - 2024. All rights reserved.