2012-11-14 102 views
1

我需要有多個遠程管理員在現場測試他們的下載速度。 Speedtest.net等都不是我們廣域網中性能的真實指標。我不希望使用iperf,因爲我需要儘量減少遠程管理員的技術知識和工作量。我不希望他們也不得不安裝任何東西。因此我需要一個簡單的批處理文件來下載一個測試文件5次。這是我到目前爲止:批處理腳本for循環不工作

@echo off 
rem localize variables to this script 
setlocal 
rem delete the test file if it already exists 
if exist %HomePath%\Downloads\100meg.test del %HomePath%\Downloads\100meg.test 
rem perform the test 5 times 
for /l %%i IN (1,1,5) DO (
    rem mark the start time 
    set STARTTIME=%TIME% 
    echo Download started at:%STARTTIME% 
    rem start download 
    C:\windows\explorer.exe http://mirror.internode.on.net/pub/test/100meg.test 
    rem check for file download completion 
    :while 
     if exist %HomePath%\Downloads\100meg.test goto wend 
     goto while 
    :wend 
    rem mark the end time 
    set ENDTIME=%TIME% 
    echo Download completed at:%ENDTIME% 
    rem convert STARTTIME and ENDTIME to centiseconds 
    set /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100) 
    set /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100) 
    rem calculate the time taken in seconds 
    set /A DURATION=(%ENDTIME%-%STARTTIME%)/100 
    echo Download took:%DURATION% seconds 
    rem delete the test file ready for next iteration 
    del %HomePath%\Downloads\100meg.test 
) 

問題是,因爲添加for並將括號括起來,它停止工作。任何人都可以闡明爲什麼這是失敗的?

謝謝!

+0

註釋掉「@echo off」,看看有什麼失敗。 – jdigital

+0

好的,首先腳本似乎設置了變量,但立即忘記它: C:\ Users \ j \ Desktop> for/L%i IN(1 1 5)DO( set STARTTIME = 11:59:26.39 回聲下載的開始: 暫停 其次,它只有通過for循環 – James

+0

單次迭代去(這個網站有未格式化的,以前的評論,我只想說,「下載開始時間:」讀取「下載開始時間: 11:59:26.39「for循環未使用時 – James

回答

3

在FOR循環中使用GOTO總會打斷循環 - 一旦使用了GOTO,剩餘的迭代就不會發生。

這是因爲CMD.EXE的工作方式。括號中的整個命令塊將被解析並一次加載到內存中。每次迭代都會執行存儲在內存中的已解析命令。這些解析的命令不包含任何標籤。 GOTO必須掃描文件,這需要打破循環。

STARTTIME的「消失」值也與整個塊被一次解析的事實有關。 %STARTTIME%在解析時展開,但在執行任何塊之前解析該命令。所以你得到了FOR命令執行前存在的值,這可能是未定義的。有一個稱爲延遲擴展的特性,可用於在執行時獲取變量的值而不是解析時間。從命令提示符處輸入HELP SET,並閱讀有關延遲擴展的部分,該部分從文檔的中途開始。

但是有一個簡單的方法讓你的代碼工作 - 只要將DO塊的內容移動到子程序中,然後在你的循環中調用例程。 (我假設你在DO子句中的邏輯是正確的)。 CALL不打破循環:-)

您必須記住在常規標籤之前放置一個EXIT/B,以便您的主代碼不會落入子程序。

@echo off 
rem localize variables to this script 
setlocal 
rem delete the test file if it already exists 
if exist %HomePath%\Downloads\100meg.test del %HomePath%\Downloads\100meg.test 
rem perform the test 5 times 
for /l %%i IN (1,1,5) do call :downloadTest 
exit /b 

:downloadTest 
rem mark the start time 
set STARTTIME=%TIME% 
echo Download started at:%STARTTIME% 
rem start download 
C:\windows\explorer.exe http://mirror.internode.on.net/pub/test/100meg.test 
rem check for file download completion 
:while 
    if exist %HomePath%\Downloads\100meg.test goto wend 
    goto while 
:wend 
rem mark the end time 
set ENDTIME=%TIME% 
echo Download completed at:%ENDTIME% 
rem convert STARTTIME and ENDTIME to centiseconds 
set /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100) 
set /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100) 
rem calculate the time taken in seconds 
set /A DURATION=(%ENDTIME%-%STARTTIME%)/100 
echo Download took:%DURATION% seconds 
rem delete the test file ready for next iteration 
del %HomePath%\Downloads\100meg.test 
exit /b 
+0

怎麼樣加入一個** GOTO:EOF **到最後GOTO「循環」,所以它返回到FOR語句? – Lizz

+0

@Lizz - Nope; GOTO:EOF和EXIT/B只能從CALL返回,而不能從GOTO返回。 GOTO:EOF和EXIT/B將在CALL尚未創建時退出批處理腳本。 – dbenham

+0

謝謝dbenham - 第一段完全是問題 - GOTO打破了循環 – James