Problem
這陣子寫了隻外掛程式,希望能簡單的透過batch做線上更新。在執行batch去解壓縮並覆蓋所有內容後(當然包含更新batch本身),batch並沒正常的執行完成。以下是我的script:
rem 前略.. "%ZIP_CMD%" x -y -o"%TEMP_DIR%" Bot.zip xcopy /i /e /y "%TEMP_DIR%" del /f Bot.zip exit 0
在複製檔案(xcopy)後,並沒執行刪除動作。也許你會說: 那幹嘛更新這隻batch? 更新batch也是可能有變動的,我又懶得寫另外一隻程式替我處理更新問題。之前曾做過修改batch中jvm的功能,也有遇到
Root Cause
正在執行的batch被修改後,非常有可能會造成接下的執行不正常。我假設「Batch是做到哪裡讀到哪裡的行為」,於是我寫了兩隻測試Batch來替我驗證這假設是否成立。
- test.bat: 複製test_tmp.bat取代自己。
- test_tmp.bat: 一堆echo。
test.bat:
@echo off set BASE=%~dp0 cp -f "%BASE%test_tmp.bat" "%BASE%test.bat"
test_tmp.bat:
@echo off set BASE=%~dp0 echo long~long~long~long~long~long~long~long~long~long~string echo long~long~long~long~long~long~long~long~long~long~string echo 123 echo 456
先看看執行結果在做解釋:
cp -f "%BASE%test_tmp.bat" "%BASE%test.bat" echo long~long~long~long~long~long~long~long~long~long~string
從test.bat與test_tmp.bat的第三行做比較可以驗證我的假設: 「Batch以行為單位,讀到哪做到哪。」 從test.bat結束位置對照到test_tmp.bat的echo內容,你也許會問說: 不是應該從g~long~long~string開始嗎? 這個問題就讓大家自行思考了。
How to?
我想到的解法是: 「修改後就結束Batch的執行。」 我們可以透過&與exit達成。直接看看範例:
@echo off set BASE=%~dp0 cp -f "%BASE%test_tmp.bat" "%BASE%test.bat" & exit /b 0 rem cp -f "%BASE%test_tmp.bat" "%BASE%test.bat" & if exist "%BASE%test.bat" echo exist & exit /b 0
我將exit動作接在複製batch後面,也可以將其它後續動作透過&串起來。這個寫法的壞處是: 可讀性不佳。但如果再改一下寫法用^做跳行就會好看些:
@echo off set BASE=%~dp0 cp -f "%BASE%test_tmp.bat" "%BASE%test.bat" &^ exit /b 0
留言
張貼留言