Upload
-
View
480
Download
1
Embed Size (px)
Citation preview
1
Batch 溫故 / 知新YiPo
2015-06-30
2
前言• 最近 自動化 正如火如荼進行。
nuuobuild_2005.bat, copy_testload.bat, Debug_Install.bat,
SkinEncrypt.bat, CopySkinEncryptFiles.bat, …
• 把事情一件件寫下來 ( 成 .bat) ,電腦替你做。• 其實蠻瑣碎而缺乏規則的,
建議多查 (/?) 、多試 ( 寫小程式 ) ,再三確認。我不直接回答你 用例子回答你
3
總覽• @ECHO OFF
• 各式符號用途• Argument/Return
• 變數兩型• IF 三招• FOR 四式
• 註解• Block
• Function
• 其他討論• 衍生閱讀
4
Hello World (in Batch)
SET /P NAME=Name: ECHO Hello, %Name%!
C:\Users\YiPo>SET /P NAME=Name:Name: YiPo
C:\Users\YiPo>ECHO Hello, YiPo!Hello, YiPo!
真的像電腦在一行行幫你輸入指令。• 方便 debug• 但也有點囉嗦名詞: prompt, echo
• SET 其實是設定環境變數,若加上 /P 可由 stdin 取得資料。• % 來 展開 環境變數 ( 不是 $) 。
5
@ECHO OFF (1)
@SET /P NAME=Name: @ECHO Hello, %Name%!
Name: YiPoHello, YiPo!
作用於該行不顯示 prompt 與 echo
6
@ECHO OFF (2)
ECHO OFF
SET /P NAME=Name: ECHO Hello, %Name%!
C:\Users\YiPo>ECHO OFFName: YiPoHello, YiPo!
執行後生效不顯示 prompt 與 echo
7
@ECHO OFF (3)
@ECHO OFF
SET /P NAME=Name: ECHO Hello, %Name%!
Name: YiPoHello, YiPo!
@ECHO OFF 就是這樣來的。( 不同於 bash 的 #!/bin/bash
8
符號總動員@ 該行不 echo
% 展開變數重新導向
< 從檔案輸入<&n 輸入至該 fd
> 輸出至檔案>&n 輸出該 fd 至| 管線
指令串接& ( 無條件 ) 串連指令&& 前面成功才執行|| 前面失敗才執行() 巢狀指令
續行: ^
跳脫字元^% ^& ^| ^( ^) ^^
0: stdin1: stdout2: stderr
9
Input/Output 與 Argument/Return
@ECHO OFFECHO %0, %*ECHO %1, %2, %3SHIFTECHO %1, %2, %3EXIT /B 56
C:\Users\YiPo\Example.bat, apple banana cat dogapple, banana, catbanana, cat, dog
C:\Users\YiPo>Example.bat apple banana cat dog
• %0 至 %9 ,沒有 %10 該怎麼辦?• EXIT 蠻難用的,無法跳出單層 batch 。
小祕訣:可以用拖拉方式餵檔案路徑給 .bat 。
10
變數兩型• %X ( 只能一個字元 )
– 指令參數 (%0-%9) 、迴圈變數 (%A-%Z, %a-%z)
– %~X (FOR /?)
• %VAR%– 環境變數– %VAR:~1,-1% 或 %VAR:str1==str2% (SET /?)
11
%1 "foo bar.txt" 原始內容%~1 foo bar.txt 除去引號%~f1 C:\Users\YiPo\foo bar.txt 絕對路徑%~d1 C: • 磁碟代號%~p1 \Users\YiPo\ • 路徑%~n1 foo bar • 檔名%~x1 .txt • 副檔名%~s1 C:\Users\YiPo\FOOBAR~1.TXT 8+3
%~a1 --a------ 檔案屬性%~t1 2015-06-29 11:30 修改日期%~z1 240 檔案大小
12
IF 三招• IF ERRORLEVEL 3– exit code >= 3
• IF foo == bar– 陷阱很多
• IF EXIST file
所以要從大的挑到小的。
13
陷阱:小心 空變數 與 空白字元 (1)
SET VAR=IF %VAR% == foo ( ECHO OK)
這個時候不應有 ( 。IF == foo (
SET VAR=foo barIF _%VAR% == _foo ( ECHO OK)
這個時候不應有 bar 。IF _foo bar == _foo (
IF _ == _foo ( IF "foo bar" == foo (
14
陷阱:小心 空變數 與 空白字元 (2)
SET VAR=foo barIF "%VAR%"=="foo bar" ( ECHO OK)
OK
IF "foo bar" == "foo bar" (
SET VAR="foo bar"IF "%VAR%"=="foo bar" ( ECHO OK)
這個時候不應有 bar""=="foo bar" 。IF ""foo bar""=="foo bar" (
快不行了…只有 %~1 可以去引號算是正解了正正解: IF "%~1"=="foo" (
15
FOR 四式FOR … %%I IN (…) DO …
• FOR 清單 ( 空白分隔的變數 )
• FOR /D, FOR /R 檔案 ( 遞迴 )
• FOR /L 數數字• FOR /F 資料剖析
在 .bat 裡要才 %%
16
應用例:從一加到十SET SUM=0FOR /L %%I IN (1,1,10) DO ( SET /A SUM+=%%I)ECHO %SUM%
55
(begin, step, end)
SET /A 還能夠算數喔!
17
應用例:讀取設定檔FOR /F %%I IN (config.ini) DO SET %%IECHO apple=%apple%, banana=%banana%, cherry=%cherry%
apple=1, banana=8, cherry=3
config.ini
apple = 1banana = 8cherry = 3
18
陷阱:延遲環境變數展開 ( 需 CMD /V:ON)
SET SUM=0FOR /L %%I IN (1,1,10) DO ( SET /A SUM+=%%I ECHO %SUM%)
0000000000
!SUM!
13610152128364555
19
註解• REM
– 標準做法– ( 過去有 |, >, < 的陷阱 )
• ::
– 其實是 GOTO 標籤– 不能加在行尾
20
Block
SETLOCALSET VAR=I'm a local variable.ECHO VAR=%VAR%ENDLOCALECHO VAR=%VAR%
VAR=I'm a local variable.VAR=
21
Function
CALL :func apple banana cherryECHO OKGOTO :EOF
:funcECHO %*GOTO :EOF
apple banana cherryOK
小心別繼續往下執行
22
利用一下 PATH 與 CD
SET TARGET_PATH=D:\Testload\ODM\Dlink\...
%TOOLS_PATH%\CabArc.exe %TARGET_PATH%\file1 ...%TOOLS_PATH%\NuGuidPatch.exe %TARGET_PATH%\file2 ...%TOOLS_PATH%\SkinEncrypt.exe %TARGET_PATH%\file3 ...CD /D %~dp0PATH tools\CabArc file1 ...NuGuidPatch file2 ...SkinEncrypt file3 ...
使用前都要手動改這行
很長一串,不易閱讀。
23
更多討論• PATH 變數內,路徑即使有空白字元也不能加雙引號。• SET ERRORLEVEL 令 %ERRORLEVEL% 不如往常。• 含空白字元的字串串接小祕訣
這樣也行: C:\"Program Files"\Java
• Windows 其實支援 symbolic link 了 (MKLINK /?)
C:\ProgramData\Oracle\Java\javapath 是為一例• 在 Makefile 裡,指令不能是大寫。
24
衍生閱讀• 善用 Command /?
– HELP 看支援的指令; SET 看可用的環境變數。• Rob van der Woude’s Scripting Pages
http://www.robvanderwoude.com/batchfiles.php
• PowerShellWindows 下一代的腳本語言