批处理在第三次尝试时正确运行,但根本不在任务管理器中
Batch runs correctly on third attempt but not in task manager at all
我已经阅读了这里的各种答案并尝试了一些但没有成功。
我的问题是脚本 "log_copy_script.cmd",我在其中有几个子例程,但其中一个表现得很奇怪。该脚本旨在获取今天的日期,减去 1 年,然后开始删除 1 年前的文件夹。它有时有效。事实上,如果我通过命令行 运行 它会首先尝试删除一个名为 nothing "" 的文件夹,然后它会只尝试月份和日期 "MMDD",然后第三次它会正确地删除"YYYYMMDD"。任何进一步的后续时间都会成功,就好像缓存了一些东西一样。
此外,当我通过 Windows 任务计划程序 运行 执行此操作时,它会 运行 并记录到我的日志文件,但每次它都会尝试删除 "" 空白。
有人知道这里发生了什么吗?谢谢。 :-/
REM Get IP and Vol Name from file, define variables
for /f "delims=" %%x in (C:/SystemHealthScripts/ip_address.txt) do set IP_ADDRESS=%%x
for /f "delims=" %%x in (C:/SystemHealthScripts/vol_name.txt) do set VOL_NAME=%%x
set MAINDIR="\%IP_ADDRESS%%VOL_NAME%"
set SUBDIR="\%IP_ADDRESS%%VOL_NAME%\%LOG_DATE%"
set LOGFILE="\%IP_ADDRESS%%VOL_NAME%\log.txt"
if [%1]==[delete_oldest] (
REM Format date
for /f "tokens=1,2,3,4 delims=/ " %%a in ("%date%") do set month=%%b&set year=%%c&set day=%%a
set LOG_DATE=%year%%month%%day%
set /A "DEL_YEAR=year-1"
set DEL_DATE=%DEL_YEAR%%month%%day%
REM Basic validation (Greater than or equal to 20160101 then valid date)
if [%DEL_DATE%] GEQ [20160101] (
call echo "%LOG_DATE% %LOG_TIME%: Deleting date '%DEL_DATE%' started" >> %LOGFILE%
call rmdir /s /q %MAINDIR%\%DEL_DATE%
call echo "%LOG_DATE% %LOG_TIME%: Deleting date '%DEL_DATE%' finished" >> %LOGFILE%
) else (
call echo "%LOG_DATE% %LOG_TIME%: ERROR in deleting date '%DEL_DATE%', validation not met!" >> %LOGFILE%
)
)
由于您没有将对 cmd
有意义的字符分配给您的变量,因此您应该安全地在 scipt 的顶部(第一行)插入一行 setlocal enabledelayedexpansion
。
对于任何代码块(带括号的代码),首先解析该块 - 解析过程的一部分是用它的 then- 替换 ANY %var%
变量当前值。由于您在代码块中分配了实例 month
,因此它在第一个 运行 上的值是 nothing - setlocal
不存在,第一个 运行 上 month
的值将用作第二个上的初始值,依此类推。
setlocal enabledelayedexpansion
做了两件事。首先,当批次结束时,环境恢复到原来的设置。所有更改都被取消,因此在任何 运行 中分配或更改的任何值都是 "reset".
它做的第二件事是允许语法 !var!
访问变量 的值,因为它在块 内发生变化(通常是由于for
循环,也是 if/else
操作的结果)。
所以 - 添加 setlocal enabledelayedexpansion
并替换 any 变量,其值在块内从 %var%
更改为 !var!
这被称为 "delayed expansion" - 关于这个主题有数百个项目。使用 search
表示很多很多例子。
一种替代方法,使用任何延迟扩展。
@echo off
REM Get IP and Vol Name from file, define variables
for /f "usebackq delims=" %%x in ("C:\SystemHealthScripts\ip_address.txt") do set "IP_ADDRESS=%%x"
for /f "usebackq delims=" %%x in ("C:\SystemHealthScripts\vol_name.txt") do set "VOL_NAME=%%x"
set "MAINDIR=\%IP_ADDRESS%%VOL_NAME%"
set "SUBDIR=\%IP_ADDRESS%%VOL_NAME%\%LOG_DATE%"
set "LOGFILE=\%IP_ADDRESS%%VOL_NAME%\log.txt"
if "%1"=="delete_oldest" CALL :delete_oldest
GOTO :EOF
:delete_oldest
REM Format date
for /f "tokens=1,2,3,4 delims=/ " %%a in ("%date%") do (
set "month=%%b"
set "year=%%c"
set "day=%%a"
)
set "LOG_DATE=%year%%month%%day%"
set /A "DEL_YEAR=year-1"
set "DEL_DATE=%DEL_YEAR%%month%%day%"
REM Basic validation (Greater than or equal to 20160101 then valid date)
if %DEL_DATE% GEQ 20160101 (
echo "%LOG_DATE% %LOG_TIME%: Deleting date '%DEL_DATE%' started" >> "%LOGFILE%"
rmdir /s /q "%MAINDIR%\%DEL_DATE%"
echo "%LOG_DATE% %LOG_TIME%: Deleting date '%DEL_DATE%' finished" >> "%LOGFILE%"
) else (
echo "%LOG_DATE% %LOG_TIME%: ERROR in deleting date '%DEL_DATE%', validation not met!" >> "%LOGFILE%"
)
我已经阅读了这里的各种答案并尝试了一些但没有成功。
我的问题是脚本 "log_copy_script.cmd",我在其中有几个子例程,但其中一个表现得很奇怪。该脚本旨在获取今天的日期,减去 1 年,然后开始删除 1 年前的文件夹。它有时有效。事实上,如果我通过命令行 运行 它会首先尝试删除一个名为 nothing "" 的文件夹,然后它会只尝试月份和日期 "MMDD",然后第三次它会正确地删除"YYYYMMDD"。任何进一步的后续时间都会成功,就好像缓存了一些东西一样。
此外,当我通过 Windows 任务计划程序 运行 执行此操作时,它会 运行 并记录到我的日志文件,但每次它都会尝试删除 "" 空白。
有人知道这里发生了什么吗?谢谢。 :-/
REM Get IP and Vol Name from file, define variables
for /f "delims=" %%x in (C:/SystemHealthScripts/ip_address.txt) do set IP_ADDRESS=%%x
for /f "delims=" %%x in (C:/SystemHealthScripts/vol_name.txt) do set VOL_NAME=%%x
set MAINDIR="\%IP_ADDRESS%%VOL_NAME%"
set SUBDIR="\%IP_ADDRESS%%VOL_NAME%\%LOG_DATE%"
set LOGFILE="\%IP_ADDRESS%%VOL_NAME%\log.txt"
if [%1]==[delete_oldest] (
REM Format date
for /f "tokens=1,2,3,4 delims=/ " %%a in ("%date%") do set month=%%b&set year=%%c&set day=%%a
set LOG_DATE=%year%%month%%day%
set /A "DEL_YEAR=year-1"
set DEL_DATE=%DEL_YEAR%%month%%day%
REM Basic validation (Greater than or equal to 20160101 then valid date)
if [%DEL_DATE%] GEQ [20160101] (
call echo "%LOG_DATE% %LOG_TIME%: Deleting date '%DEL_DATE%' started" >> %LOGFILE%
call rmdir /s /q %MAINDIR%\%DEL_DATE%
call echo "%LOG_DATE% %LOG_TIME%: Deleting date '%DEL_DATE%' finished" >> %LOGFILE%
) else (
call echo "%LOG_DATE% %LOG_TIME%: ERROR in deleting date '%DEL_DATE%', validation not met!" >> %LOGFILE%
)
)
由于您没有将对 cmd
有意义的字符分配给您的变量,因此您应该安全地在 scipt 的顶部(第一行)插入一行 setlocal enabledelayedexpansion
。
对于任何代码块(带括号的代码),首先解析该块 - 解析过程的一部分是用它的 then- 替换 ANY %var%
变量当前值。由于您在代码块中分配了实例 month
,因此它在第一个 运行 上的值是 nothing - setlocal
不存在,第一个 运行 上 month
的值将用作第二个上的初始值,依此类推。
setlocal enabledelayedexpansion
做了两件事。首先,当批次结束时,环境恢复到原来的设置。所有更改都被取消,因此在任何 运行 中分配或更改的任何值都是 "reset".
它做的第二件事是允许语法 !var!
访问变量 的值,因为它在块 内发生变化(通常是由于for
循环,也是 if/else
操作的结果)。
所以 - 添加 setlocal enabledelayedexpansion
并替换 any 变量,其值在块内从 %var%
更改为 !var!
这被称为 "delayed expansion" - 关于这个主题有数百个项目。使用 search
表示很多很多例子。
一种替代方法,使用任何延迟扩展。
@echo off
REM Get IP and Vol Name from file, define variables
for /f "usebackq delims=" %%x in ("C:\SystemHealthScripts\ip_address.txt") do set "IP_ADDRESS=%%x"
for /f "usebackq delims=" %%x in ("C:\SystemHealthScripts\vol_name.txt") do set "VOL_NAME=%%x"
set "MAINDIR=\%IP_ADDRESS%%VOL_NAME%"
set "SUBDIR=\%IP_ADDRESS%%VOL_NAME%\%LOG_DATE%"
set "LOGFILE=\%IP_ADDRESS%%VOL_NAME%\log.txt"
if "%1"=="delete_oldest" CALL :delete_oldest
GOTO :EOF
:delete_oldest
REM Format date
for /f "tokens=1,2,3,4 delims=/ " %%a in ("%date%") do (
set "month=%%b"
set "year=%%c"
set "day=%%a"
)
set "LOG_DATE=%year%%month%%day%"
set /A "DEL_YEAR=year-1"
set "DEL_DATE=%DEL_YEAR%%month%%day%"
REM Basic validation (Greater than or equal to 20160101 then valid date)
if %DEL_DATE% GEQ 20160101 (
echo "%LOG_DATE% %LOG_TIME%: Deleting date '%DEL_DATE%' started" >> "%LOGFILE%"
rmdir /s /q "%MAINDIR%\%DEL_DATE%"
echo "%LOG_DATE% %LOG_TIME%: Deleting date '%DEL_DATE%' finished" >> "%LOGFILE%"
) else (
echo "%LOG_DATE% %LOG_TIME%: ERROR in deleting date '%DEL_DATE%', validation not met!" >> "%LOGFILE%"
)