Windows 批处理在第三次尝试时正确运行,但根本不在任务管理器中运行
我已经通读了这里的各种答案,并尝试了一些,但没有运气 我的问题是脚本“log\u copy\u script.cmd”,我有几个子程序在里面,但其中一个执行起来非常奇怪。该脚本旨在获取今天的日期,减去1年,然后开始删除日期为1年前的文件夹。它有时起作用。事实上,如果我通过命令行运行它,它将首先尝试删除名为nothing“”的文件夹,然后它将只尝试月和日的“MMDD”,然后第三次它将正确地执行“YYMMDD”。任何后续的时间都会成功,就好像缓存了什么东西一样 另外,当我通过Windows任务调度器运行此任务时,它将运行并记录到我的日志文件中,但每次它都会尝试删除“”空白 有人知道这里发生了什么吗?谢谢-/Windows 批处理在第三次尝试时正确运行,但根本不在任务管理器中运行,windows,batch-file,cmd,directory,exe,Windows,Batch File,Cmd,Directory,Exe,我已经通读了这里的各种答案,并尝试了一些,但没有运气 我的问题是脚本“log\u copy\u script.cmd”,我有几个子程序在里面,但其中一个执行起来非常奇怪。该脚本旨在获取今天的日期,减去1年,然后开始删除日期为1年前的文件夹。它有时起作用。事实上,如果我通过命令行运行它,它将首先尝试删除名为nothing“”的文件夹,然后它将只尝试月和日的“MMDD”,然后第三次它将正确地执行“YYMMDD”。任何后续的时间都会成功,就好像缓存了什么东西一样 另外,当我通过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
对于任何代码块(括号中的代码),首先解析该块-解析过程的一部分是将任何%var%
变量替换为其当前值。由于您在代码块内指定了例如month
,因此第一次运行时它的值为零-由于setlocal
不存在,第一次运行时month
的值将用作第二次运行时它的初始值,依此类推
setlocal enabledelayedexpansion
做两件事。首先,当批处理结束时,环境将恢复到其原始设置。所有更改都将被备份,因此在任何运行中分配或更改的任何值都将被“重置”
它做的第二件事是允许语法!瓦尔
访问变量在块内变化时的值(通常是由于for
循环,但也是由于if/else
操作)
因此-添加setlocal enabledelayedexpansion
,并将块内值从%var%
更改为的任何变量替换为!瓦尔代码>
这被称为“延迟扩展”——在这个主题上有数百个项目。使用search
搜索多个、多个、多个示例。由于您没有为变量分配对cmd
有意义的字符,因此应该可以安全地在scipt顶部(第一行)插入一行setlocal enabledelayedexpansion
对于任何代码块(括号中的代码),首先解析该块-解析过程的一部分是将任何%var%
变量替换为其当前值。由于您在代码块内指定了例如month
,因此第一次运行时它的值为零-由于setlocal
不存在,第一次运行时month
的值将用作第二次运行时它的初始值,依此类推
setlocal enabledelayedexpansion
做两件事。首先,当批处理结束时,环境将恢复到其原始设置。所有更改都将被备份,因此在任何运行中分配或更改的任何值都将被“重置”
它做的第二件事是允许语法!瓦尔
访问变量在块内变化时的值(通常是由于for
循环,但也是由于if/else
操作)
因此-添加setlocal enabledelayedexpansion
,并将块内值从%var%
更改为的任何变量替换为!瓦尔代码>
这被称为“延迟扩展”——在这个主题上有数百个项目。使用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%"
)
一种替代方法,它使用任何延迟扩展
@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%"
)
也许我应该指出,出于不同的原因,可以同时调用此脚本。我习惯于Java和运行实例,也许这不是那样的?也许我的例程需要单独的脚本文件?@magoo为您的问题提供了一个很好的描述,但是您可以通过创建一个函数而不是使用IF块来缓解问题。您可以创建一个名为:delete_oldest
的标签,您可以使用带有输入参数的CALL命令代替IF命令<代码>调用:%~1
。也许我应该指出,出于不同的原因,可以同时调用此脚本。我习惯于Java和运行实例,也许这不是那样的?也许我的例程需要单独的脚本文件?@magoo为您的问题提供了一个很好的描述,但是您可以通过创建一个函数而不是使用IF块来缓解问题。您可以创建一个名为:delete_oldest
的标签,您可以使用带有输入参数的CALL命令代替IF命令<代码>呼叫:%~1
。您好,谢谢您的详细回复。我现在要去实验室做些改变。我在Java等其他语言中没有看到过这个问题。我猜大多数其他语言中的全局变量已经首先解析了代码块,所以我永远不会遇到这个问题。这些更改非常有效。事实上,它看起来也解决了我的一些其他问题!再次感谢!嗨,谢谢你的详细回复。我现在要去实验室做些改变。我在Java等其他语言中没有看到过这个问题。我猜大多数其他语言中的全局变量已经首先解析了代码块,所以我永远不会遇到这个问题。这些更改非常有效。事实上,它看起来也解决了我的一些其他问题!再次感谢!谢谢你!这是我很长时间以来第一次编写windows脚本,与BASH完全不同。