24
Batch 溫溫 / 溫溫 YiPo 2015-06-30 1

Batch 溫故/知新

  • Upload
    -

  • View
    480

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Batch 溫故/知新

1

Batch 溫故 / 知新YiPo

2015-06-30

Page 2: Batch 溫故/知新

2

前言• 最近 自動化 正如火如荼進行。

nuuobuild_2005.bat, copy_testload.bat, Debug_Install.bat,

SkinEncrypt.bat, CopySkinEncryptFiles.bat, …

• 把事情一件件寫下來 ( 成 .bat) ,電腦替你做。• 其實蠻瑣碎而缺乏規則的,

建議多查 (/?) 、多試 ( 寫小程式 ) ,再三確認。我不直接回答你 用例子回答你

Page 3: Batch 溫故/知新

3

總覽• @ECHO OFF

• 各式符號用途• Argument/Return

• 變數兩型• IF 三招• FOR 四式

• 註解• Block

• Function

• 其他討論• 衍生閱讀

Page 4: Batch 溫故/知新

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 取得資料。• % 來 展開 環境變數 ( 不是 $) 。

Page 5: Batch 溫故/知新

5

@ECHO OFF (1)

@SET /P NAME=Name: @ECHO Hello, %Name%!

Name: YiPoHello, YiPo!

作用於該行不顯示 prompt 與 echo

Page 6: Batch 溫故/知新

6

@ECHO OFF (2)

ECHO OFF

SET /P NAME=Name: ECHO Hello, %Name%!

C:\Users\YiPo>ECHO OFFName: YiPoHello, YiPo!

執行後生效不顯示 prompt 與 echo

Page 7: Batch 溫故/知新

7

@ECHO OFF (3)

@ECHO OFF

SET /P NAME=Name: ECHO Hello, %Name%!

Name: YiPoHello, YiPo!

@ECHO OFF 就是這樣來的。( 不同於 bash 的 #!/bin/bash

Page 8: Batch 溫故/知新

8

符號總動員@ 該行不 echo

% 展開變數重新導向

< 從檔案輸入<&n 輸入至該 fd

> 輸出至檔案>&n 輸出該 fd 至| 管線

指令串接& ( 無條件 ) 串連指令&& 前面成功才執行|| 前面失敗才執行() 巢狀指令

續行: ^

跳脫字元^% ^& ^| ^( ^) ^^

0: stdin1: stdout2: stderr

Page 9: Batch 溫故/知新

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 。

Page 10: Batch 溫故/知新

10

變數兩型• %X ( 只能一個字元 )

– 指令參數 (%0-%9) 、迴圈變數 (%A-%Z, %a-%z)

– %~X (FOR /?)

• %VAR%– 環境變數– %VAR:~1,-1% 或 %VAR:str1==str2% (SET /?)

Page 11: Batch 溫故/知新

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 檔案大小

Page 12: Batch 溫故/知新

12

IF 三招• IF ERRORLEVEL 3– exit code >= 3

• IF foo == bar– 陷阱很多

• IF EXIST file

所以要從大的挑到小的。

Page 13: Batch 溫故/知新

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 (

Page 14: Batch 溫故/知新

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" (

Page 15: Batch 溫故/知新

15

FOR 四式FOR … %%I IN (…) DO …

• FOR 清單 ( 空白分隔的變數 )

• FOR /D, FOR /R 檔案 ( 遞迴 )

• FOR /L 數數字• FOR /F 資料剖析

在 .bat 裡要才 %%

Page 16: Batch 溫故/知新

16

應用例:從一加到十SET SUM=0FOR /L %%I IN (1,1,10) DO ( SET /A SUM+=%%I)ECHO %SUM%

55

(begin, step, end)

SET /A 還能夠算數喔!

Page 17: Batch 溫故/知新

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

Page 18: Batch 溫故/知新

18

陷阱:延遲環境變數展開 ( 需 CMD /V:ON)

SET SUM=0FOR /L %%I IN (1,1,10) DO ( SET /A SUM+=%%I ECHO %SUM%)

0000000000

!SUM!

13610152128364555

Page 19: Batch 溫故/知新

19

註解• REM

– 標準做法– ( 過去有 |, >, < 的陷阱 )

• ::

– 其實是 GOTO 標籤– 不能加在行尾

Page 20: Batch 溫故/知新

20

Block

SETLOCALSET VAR=I'm a local variable.ECHO VAR=%VAR%ENDLOCALECHO VAR=%VAR%

VAR=I'm a local variable.VAR=

Page 21: Batch 溫故/知新

21

Function

CALL :func apple banana cherryECHO OKGOTO :EOF

:funcECHO %*GOTO :EOF

apple banana cherryOK

小心別繼續往下執行

Page 22: Batch 溫故/知新

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 ...

使用前都要手動改這行

很長一串,不易閱讀。

Page 23: Batch 溫故/知新

23

更多討論• PATH 變數內,路徑即使有空白字元也不能加雙引號。• SET ERRORLEVEL 令 %ERRORLEVEL% 不如往常。• 含空白字元的字串串接小祕訣

這樣也行: C:\"Program Files"\Java

• Windows 其實支援 symbolic link 了 (MKLINK /?)

C:\ProgramData\Oracle\Java\javapath 是為一例• 在 Makefile 裡,指令不能是大寫。

Page 24: Batch 溫故/知新

24

衍生閱讀• 善用 Command /?

– HELP 看支援的指令; SET 看可用的環境變數。• Rob van der Woude’s Scripting Pages

http://www.robvanderwoude.com/batchfiles.php

• PowerShellWindows 下一代的腳本語言