The command date
带参数/T
以当前用户帐户配置的国家/地区定义的格式输出当前日期。通过引用动态可以访问完全相同的日期字符串环境变量 DATE
例如与%DATE%
.
The command 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
的输出command date
处理STDOUT该命令进程在后台的捕获是FOR分别执行批处理文件的Windows命令处理器实例。
使用以下命令将捕获的行分成三个子字符串/
作为分配给循环变量的字符串分隔符a
, b
and c
它们以相反的顺序连接在一起,并使用下划线作为分隔符。
通过替换可以更快地完成此任务'date /t'
by "%DATE%"
。在这种情况下FOR处理日期string通过已经运行的扩展cmd.exe
在执行之前解析此命令行FOR。所以不再有一个开始cmd.exe
在后台并捕获其输出只是为了处理相同的日期string这使得批处理文件的执行速度更快一些。
对于'time /t'
可以替换为"%TIME%"
.
但两人FOR可以通过使用字符串替换来完全优化循环,例如答案中所描述的%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% 是什么意思? https://stackoverflow.com/a/37236739/3074564与区域相关的日期和时间格式是众所周知的,例如通过在命令提示符窗口中运行:
echo %DATE% %TIME%
此命令根据配置的国家/地区以德国日期/时间格式在我的计算机上输出:
24.07.2019 20:15:29,90
在此输出中可以看出,原始代码无法在我的 Windows 计算机上使用我的帐户运行,因为日期字符串包含.
并不是/
并且时间字符串包含逗号。
因此,最好使用与区域无关的解决方案,如答案中详细解释的那样为什么%date%在按计划任务执行的批处理文件中产生不同的结果? https://stackoverflow.com/a/44670322/3074564缺点是执行wmic.exe
需要比cmd.exe
需要将日期和时间字符串重新格式化为yyyy_MM_dd_HHmm
。但是,批处理文件每天执行的频率很可能不是很高,因此获取这种格式的日期/时间的执行是否需要几毫秒或大约一秒并不重要。
在这种情况下,复制整个文件夹并不是真正必要的。将其重命名为:
ren "%ApplicationDeploymentFolderPath%\release" "%backup_folder%"
命令move
也可以使用 if 命令ren
由于未知原因无法使用。
然而,主要问题是缺乏关于如何以及何时使用的知识延迟扩张 https://ss64.com/nt/delayedexpansion.html。打开一个命令提示符 https://www.howtogeek.com/235101/10-ways-to-open-the-command-prompt-in-windows-10/, run set /?
并阅读输出帮助解释IF and a FOR示例延迟环境变量扩展。
这里的问题是backup_folder
未在执行引用它的命令行时定义%backup_folder%
因为所有的发生%variable%
被Windows命令处理器取代,已经解析整个命令块,从这里开始(
on 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
这可以通过以下方式看到调试批处理文件 https://stackoverflow.com/a/42448601/3074564.
也可以看看:Windows 命令解释器 (CMD.EXE) 如何解析脚本? https://stackoverflow.com/questions/4094699/
解决方案是通过更改第一个来避免命令块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 /?