0

私の作業用バッチ ファイルは、リモート サーバーの長いリストをスキャンし、そこにあるものをすべてローカル サーバーにコピーし、ログ ファイルでキーワードをチェックし、キーワードが見つかった場合は電子メールを送信します。ログファイルが空の場合でも、常にメールを送信していることに気付きました。

FOR両方のループが%1出力に変数を使用していることを発見しましECHO %1:servermove。より良い説明がない%1ため、ループ間で null にリセットされません。

SETLOCAL ENABLEDELAYEDEXPANSION私はほぼ十数の SO 投稿を確認しましたが、これを使用するとこれが解決すると確信しています。それが私の理解の終わりであり、これまでのところ私は成功していません。

関連するコードは次のとおりです。

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とその対応物を配置し、 toを変更しても機能しません。ENDLOCAL%%A!A!

誰かが私のやり方の誤りを親切に指摘し、これを解決するのに役立つ提案やリソースを提供してくれませんか?

4

3 に答える 3

1

%1は、コマンドライン (メイン プロシージャ内) から、または のプロシージャ名に続くパラメータのいずれかから、プロシージャに提供される最初のパラメータcall :procedurename parameter1です。

あなたの場合、%1to:servermoveは からのエントリでSourceServers.txtあり、%1to:searchlogは からの各行%LOGFILE%です。

バッチを検閲したので、投稿した内容はほとんど意味がありません。たとえば、:searchlogsルーチンは最初の行を取り、その最初の行にターゲット文字列が含まれているかどうかに応じてor%LOGFILE%に移動します。そこから何をするのかはわかりません。successmailcleanlogs\\nt

私たちはXY 問題に直面しています- 問題ではなく、解決策を修正しようとしています。


date最初の問題:ユーザー変数として使用しないでください。これは日付を含む「魔法の変数」ですset、特定のステートメントによってオーバーライドされます。

:servermoveの各エントリに対して実行すると、そのサーバーSourceServers.txtからディレクトリ リストが蓄積\CreditFileImagesTransmission\*.*されます。-これらのファイルをnt980a3日付/タイムスタンプ付きでサーバーにコピーしますが、ソースサーバー名は含めないため、どこにでも重複する名前があると以前のバージョンが上書きされます。%1宛先名に含めることをお勧めします。- サブディレクトリの削除 - ファイルの削除。

\\%1\CreditFileImagesTransmission\ディレクトリを削除してから、再作成することをお勧めします。

また、余分な行を追加することをお勧めします

goto :eof

行の後del /q /s...。これにより、実行がファイルの終わりに転送され (コロン:eofが必要)、余分に見えるかもしれませんが、ルーチンに定義済みのエンドポイントがあることが保証されます:servermove。新しいコードに続きます。

:cleanuplogs各サーバーが処理された後、ルーチンに進みます。これにより、45 日より古いログが削除されると思われます。

あなたの次の発言は本当の問題です。それが行うことは、ログファイルの最初の行を取得することです (これには、最初に"%DATE% at %HH%%MN%"設定したように解決された日付が含まれており、この行を で処理し:searchlogます。この行には何もない\\ntため、errorlevel1 に設定され、バッチは(キーワードなので、私の見解では適切なラベルではありません)に進み:EXITます; を実行しexit、バッチを終了する必要があります。

これは実際に行っていることではないようで、その理由を説明するのが途方に暮れています。

変更することをお勧めします

: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

しかし、私はそれをテストすることはできません...

于 2014-07-24T23:58:52.037 に答える