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

More Related Content

What's hot

Phpをいじり倒す10の方法
Phpをいじり倒す10の方法Phpをいじり倒す10の方法
Phpをいじり倒す10の方法
Moriyoshi Koizumi
 

What's hot (20)

Phpをいじり倒す10の方法
Phpをいじり倒す10の方法Phpをいじり倒す10の方法
Phpをいじり倒す10の方法
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
 
OPcache の最適化器の今
OPcache の最適化器の今OPcache の最適化器の今
OPcache の最適化器の今
 
PlaySQLAlchemyORM2017.key
PlaySQLAlchemyORM2017.keyPlaySQLAlchemyORM2017.key
PlaySQLAlchemyORM2017.key
 
PostgreSQL on EXT4, XFS, BTRFS and ZFS
PostgreSQL on EXT4, XFS, BTRFS and ZFSPostgreSQL on EXT4, XFS, BTRFS and ZFS
PostgreSQL on EXT4, XFS, BTRFS and ZFS
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説
 
Python/Django를 이용한 쇼핑몰 구축(2018 4월 Django Girls Seoul)
Python/Django를 이용한 쇼핑몰 구축(2018 4월 Django Girls Seoul)Python/Django를 이용한 쇼핑몰 구축(2018 4월 Django Girls Seoul)
Python/Django를 이용한 쇼핑몰 구축(2018 4월 Django Girls Seoul)
 
高負荷に耐えうるWebApplication Serverの作り方
高負荷に耐えうるWebApplication Serverの作り方高負荷に耐えうるWebApplication Serverの作り方
高負荷に耐えうるWebApplication Serverの作り方
 
OpenERP Performance Benchmark
OpenERP Performance BenchmarkOpenERP Performance Benchmark
OpenERP Performance Benchmark
 
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
 
PHP 5.5ネーティブキャッシュの話
PHP 5.5ネーティブキャッシュの話PHP 5.5ネーティブキャッシュの話
PHP 5.5ネーティブキャッシュの話
 
twMVC#46_SQL Server 資料分析大躍進 Machine Learning Services
twMVC#46_SQL Server 資料分析大躍進 Machine Learning ServicestwMVC#46_SQL Server 資料分析大躍進 Machine Learning Services
twMVC#46_SQL Server 資料分析大躍進 Machine Learning Services
 
Celery의 빛과 그림자
Celery의 빛과 그림자Celery의 빛과 그림자
Celery의 빛과 그림자
 
Odoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best PracticesOdoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best Practices
 
Carthageについて知りたいn個のこと
Carthageについて知りたいn個のことCarthageについて知りたいn個のこと
Carthageについて知りたいn個のこと
 
Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
Using F# and genetic programming to play computer bridge
Using F# and genetic programming to play computer bridgeUsing F# and genetic programming to play computer bridge
Using F# and genetic programming to play computer bridge
 

Batch 溫故/知新

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