2017-03-03 73 views
0

我已閱讀了各種答案,並嘗試了幾次,但沒有運氣。批次在第三次嘗試中正確運行,但在任務管理器中完全沒有運行

我的問題是腳本「log_copy_script.cmd」,我有一些子程序,但其中一個是非常奇怪的行爲。該腳本旨在獲取今天的日期,減去1年,然後開始刪除1年前的文件夾。它有時會起作用。事實上,如果我通過命令行運行它,它將首先嚐試刪除一個名爲「」的文件夾,然後它將嘗試只是月份和日期「MMDD」,然後第三次它將正確執行「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

對於任何碼塊(parenthesised代碼),該塊被首先被解析 - 和解析過程的一部分,是與它的當時的電流值,以取代ANY%var%變量。由於您在代碼塊內分配了例如month,因此它在第一次運行時的值爲沒有任何 - 如果setlocal不存在,則第一次運行時month的值將用作第二次的初始值,因此上。

setlocal enabledelayedexpansion做了兩件事。首先,批次結束時,環境恢復到其原始設置。所有更改都會被退出,因此任何運行中分配或更改的值都會「重置」。

它做的第二件事情是讓語法!var!訪問變量的值,因爲它的塊內改變(通常爲for循環的結果,而且還作爲if/else操作的結果)。

所以 - 添加setlocal enabledelayedexpansion和替換任何變量,其值的變化從%var%塊內!var!

這被稱爲「延遲擴展」 - 有數百個項目上SO上的對象。使用search有許多很多很多的例子。

+0

嗨,非常詳細的答覆謝謝。我現在要去實驗室做出改變。我還沒有在Java等其他語言中看到過這個問題我猜測大多數其他語言的全局變量已經先解析了代碼塊,所以我永遠不會遇到這個問題。 – Jon557

+0

這些更改完美地工作。事實上,它看起來已經解決了我的一些其他問題!再次感謝! – 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

布里爾謝謝!這是我第一次寫很長一段時間的Windows腳本,與BASH完全不同。我會玩你的改變謝謝。 – Jon557

相關問題