2017-03-03 10 views
0

ここではさまざまな回答を読んだことがあります。バッチは3回目の試行で正しく実行されますが、タスクマネージャでは全く実行されません。

私の問題はスクリプト "log_copy_script.cmd"にありますが、その中にいくつかのサブルーチンがありますが、1つは非常に奇妙です。このスクリプトは、今日の日付を取得し、1年を差し引いた後、1年前のフォルダの削除を開始するためのものです。時にはうまくいく。実際にコマンドラインで実行すると、まず何も名前のついていないフォルダを削除しようとします。それから、月と日の "MMDD"を試してから、3回目に "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% 
) 
) 
+0

多分私はこのスクリプトが別の理由で同時に呼び出されることを指摘しておきます。私はJavaとインスタンスを実行するために使用して、多分これはそうではない?多分私のルーチンは別々のスクリプトファイルを必要としますか? – Jon557

+0

@magooは問題の詳細な説明を提供しますが、IFブロックを使用する代わりに関数を作成することで問題を緩和できます。 ':delete_oldest'という名前のラベルを作成し、IFコマンドの代わりに入力パラメータとともにCALLコマンドを使うだけでよいでしょう。 'CALL:%〜1'。 – Squashman

答えて

2

あなたが変数にcmdに意味を持つ文字を割り当てていないので、あなたがザ・スクリプト(最初の行)の先頭に行setlocal enabledelayedexpansionを挿入しても安全でなければなりません。任意のコードブロック(括弧のコード)で

、ブロックが最初に解析されている - と解析手順の一部は、その後、電流値とANY%var%変数を交換することです。コードブロック内にmonthというコードブロックを割り当てているため、最初の実行時の値はではありません。 - setlocalが存在しない場合、最初の実行ではmonthの値が2番目の値で初期値として使用されますに。

setlocal enabledelayedexpansionの2つのことがあります。まず、バッチが終了すると、環境は元の設定に復元されます。すべての変更がバックアウトされるため、実行中に割り当てられたり変更された値はすべて「リセット」されます。それがない

第二のものは、それが(通常forループの結果としてだけでなく、if/else動作の結果として)ブロック内変化として構文!var!が可変の値にアクセスできるようにすることです。

だから - setlocal enabledelayedexpansion追加し、その値が変化%var%からブロック内!var!

にこれを「遅延拡張」として知られている任意変数を置き換える - SO主題での項目の何百もあります。多数の多くの例にはsearchを使用してください。

+0

こんにちは、非常に詳細な応答に感謝します。私は今、研究室に行って、変更を加えるでしょう。私はJavaなどの他の言語でこの問題を見ていない他のほとんどの言語のグローバル変数はすでにコードブロックを解析しているので、この問題は発生しません。 – Jon557

+0

これらの変更は完全に機能しました。それは私の他のissuseのいくつかを解決したようにそれは見えます!再度、感謝します! – Jon557

1

任意の遅延拡張を使用する代替アプローチ。

@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%" 
) 
+0

Brillありがとう! Windowsスクリプトを書くのは初めてのことですが、それはBASHとはまったく異なります。私はあなたの変更のおかげで遊ぶよ。 – Jon557

関連する問題