2014-07-24 59 views
0

我的工作批處理文件掃描一長串遠程服務器,將任何內容複製到本地服務器,檢查日誌文件中的關鍵字,以及是否找到關鍵字發送電子郵件。我注意到它總是發送電子郵件,即使有一個空白的日誌文件。兩個使用%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

%1是提供給該過程的第一個參數 - 無論是從命令行(在主過程)或以下在call :procedurename parameter1程序名稱的參數。

你的情況,%1:servermoveSourceServers.txt%1:searchlog條目從%LOGFILE%每一行。

既然你已經審查你的批處理,你發佈的內容沒有多大意義。例如,:searchlogs例程將採用%LOGFILE%的第一行,並根據第一行是否包含目標字符串\\nt轉到successmailcleanlogs。它從那裏做了什麼,我們不知道。

我們遇到了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 

,但我不能測試...

+0

對不起;我不打算審查有關的信息。它看起來並不重要。我已經更新它以包含文件的全文。再看一遍,我最好的猜測是第一個'FOR'loop將%1設置爲文本列表中的最後一個服務器名稱(nt-whtever),第二個循環提取相同的%1,它始終是'> nul' – UserUnknown

+0

我使用了@ foxidrive和你自己的'GOTO:EOF'建議,並將':mailtest'部分的代碼改爲你的建議變體。這工作很好。現在我更好地理解了'goto:eof'的使用,以及搜索文本的新方法,我可以在其他項目中使用它。非常有用和偉大的新知識 - 謝謝! – UserUnknown

0

我覺得你不能將第一個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

1
: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