两个使用%1的循环 - 延迟扩展?
我的工作批处理文件扫描一长串远程服务器,将任何内容复制到本地服务器,检查日志文件中的关键字,以及是否找到关键字发送电子邮件。我注意到它总是发送电子邮件,即使有一个空白的日志文件。两个使用%1的循环 - 延迟扩展?
我发现这两个FOR
循环使用%1
变量的输出 - 在ECHO %1
看到和被叫:servermove
的每一行。由于缺少更好的解释,因此不会将%1
重置为循环之间的空值。
我回顾了几十个SO帖子,并且使用SETLOCAL ENABLEDELAYEDEXPANSION
可以解决这个问题。那就是我的理解到此为止,而我迄今还没有成功。
下面是相关代码:
SET DATE=%date:~4,2%-%date:~7,2%-%date:~10,4%
SET HH=%time:~0,2%
SET MN=%time:~3,2%
SET TSTAMP=Time Run is %HH%%MN%
SET DATETIME=%DATE% at %HH%%MN%
SET LOGFILE="\\nt980a3\CreditFileImagesTransmission\LogFiles\%DATETIME%-File Move Log.txt"
SET MailDst=
SET MailSrc=
SET MailSrcName=Center to LDSD File Mover
SET OKMailSub=A Branch Has Sent You Some Files
ECHO %DATETIME% > %LOGFILE%
ECHO. >> %LOGFILE%
FOR /F "tokens=1" %%A IN (%~dp0SourceServers.txt) DO CALL :ServerMove %%A
:cleanuplogs
PUSHD "\\nt980a3\CreditFileImagesTransmission\LogFiles" &&(
FORFILES /S /M *.txt /D -45 /C "CMD /C DEL /Q @path"
) & POPD
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
:successmail
IF EXIST %temp%\to.txt DEL %temp%\to.txt
FOR %%a IN (%MailDst%) DO ECHO %%a>>%temp%\to.txt
"%~dp0sendmail.exe" /TO=%temp%\to.txt /FROM=%MailSrcName% ^<%MailSrc%^> /REF=%OKMailSub% /MESSAGE=%LOGFILE% /HOST=
:exit
EXIT
:ServerMove
DIR /S /B \\%1\CreditFileImagesTransmission\*.* >> %LOGFILE%
XCOPY /E /C /I /Y "\\%1\CreditFileImagesTransmission\*.*" "\\nt980a3\CreditFileImagesTransmission\%DATE%\%HH%%MN%\"
FOR /D %%P IN ("\\%1\CreditFileImagesTransmission\*.*") DO RMDIR "%%P" /Q /S
DEL /Q /S "\\%1\CreditFileImagesTransmission\*.*"
我试图改变:mailtest
使用在这两种情况下%%B
但也失败。在一个或另一个循环之前放置SETLOCAL ENABLEDELAYEDEXPANSION
及其对应物ENDLOCAL
并将%%A
更改为!A!
也不起作用。
有人会以我的方式指出错误,并提供建议或资源,这将有助于我解决这个问题吗?
%1
是提供给该过程的第一个参数 - 无论是从命令行(在主过程)或以下在call :procedurename parameter1
程序名称的参数。
你的情况,%1
到:servermove
为SourceServers.txt
和%1
到:searchlog
条目从%LOGFILE%
每一行。
既然你已经审查你的批处理,你发布的内容没有多大意义。例如,:searchlogs
例程将采用%LOGFILE%
的第一行,并根据第一行是否包含目标字符串\\nt
转到successmail
或cleanlogs
。它从那里做了什么,我们不知道。
我们遇到了XY problem - 试图修复解决方案,而不是问题。
第一个问题:不要使用date
作为用户变量。这是一个“魔术变量”,其中包含日期,但是它被特定的set
声明覆盖。
已经为SourceServers.txt
每个条目运行:servermove
,你是 - 从\CreditFileImagesTransmission\*.*
该服务器上积累了目录列表。 - 将这些文件复制到服务器nt980a3
,日期/时间戳记但不包括源服务器名称,因此任何重复的名称都会覆盖较早的版本。我建议你在目的地名称中加入%1
。 - 删除子目录 - 删除文件。
我建议你只是删除目录\\%1\CreditFileImagesTransmission\
,然后重新创建它。
我也建议您在del /q /s...
行后添加一个额外的行
goto :eof
。这将导致执行被转移到文件结尾(需要:eof
中的冒号)并且可能看起来是多余的,但它确保该例程具有定义的端点 - 如果添加进一步的例程,则没有办法:servermove
例程将继续进入您的新代码。
在处理好每个服务器后,您继续执行:cleanuplogs
例程,我认为该例程会删除超过45天的日志。
你的下一个陈述是一个真正的问题。它会做的是抓取日志文件的第一行(其中包含"%DATE% at %HH%%MN%"
,并且已按照您在开始时设置的日期解析日期文件,然后在:searchlog
中处理此行;此行中没有\\nt
,因此设置errorlevel
到1,批量进行到:EXIT
(我认为这不是一个好的标签,因为它是一个关键字);执行exit
并应该终止批处理
这似乎不是它实际上在做什么,而我茫然“M解释为什么。
我建议改变
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
到
:mailtest
find "\\nt" %LOGFILE%>NUL
IF NOT ERRORLEVEL 1 GOTO successmail
:failmail
echo "\\nt" was found in the log
pause
GOTO exit
,但我不能测试...
我觉得你不能将第一个for循环的%1传给其他人。尝试将其转换为另一个变量,如下所示。
:ServerMove
set servername=%1
DIR /S /B \\%servername%\CreditFileImagesTransmission\*.* >> %LOGFILE%
XCOPY /E /C /I /Y "\\%servername%\CreditFileImagesTransmission\*.*" "\\nt980a3\CreditFileImagesTransmission\%DATE%\%HH%%MN%\"
FOR /D %%P IN ("\\%servername%\CreditFileImagesTransmission\*.*") DO RMDIR "%%P" /Q /S
DEL /Q /S "\\%servername%\CreditFileImagesTransmission\*.*"
干杯,G
:mailtest
FOR /F "tokens=*" %%A IN (%LOGFILE%) DO CALL :searchlog "%%A"
您在这里缺少一个GOTO :EOF
或相似的goto,因为它会下降至低于一次以上是常规完了。
:searchlog
ECHO %1 | find "\\nt">NUL
IF NOT ERRORLEVEL 1 GOTO successmail
GOTO exit
对不起;我不打算审查有关的信息。它看起来并不重要。我已经更新它以包含文件的全文。再看一遍,我最好的猜测是第一个'FOR'loop将%1设置为文本列表中的最后一个服务器名称(nt-whtever),第二个循环提取相同的%1,它始终是'> nul' – UserUnknown
我使用了@ foxidrive和你自己的'GOTO:EOF'建议,并将':mailtest'部分的代码改为你的建议变体。这工作很好。现在我更好地理解了'goto:eof'的使用,以及搜索文本的新方法,我可以在其他项目中使用它。非常有用和伟大的新知识 - 谢谢! – UserUnknown