模塊調用
1. ? 如何在一個腳本的執行中調用另外一個腳本文件?
利用 Call 命令的兩種用法來實現該功能:
l?????? 調用另外一個腳本文件:
CALL [[<Drive>:]<Path>]<batch-file-name> [<parameters>]
注意
:
(1) ??? 如果直接在腳本文件直接調用另外腳本,則子腳本正?;虍惓M顺?/span> (exit /b 語句 ) 都會導致父腳本的退出。直接寫腳本或可執行文件相當于將子腳本的命令展開在父腳本中。
(2) ??? Call 命令則是執行腳本,獲得子腳本的退出代碼,設置 errorlevel ,然后返回父腳本繼續執行。
(3) ??? Call 命令不會啟動命令解釋器的新的子進程,還是在執行父腳本的進程中執行子腳本, 因此子腳本中對環境變量的改變也會影響父腳本的執行。
(4) ??? 另外 Call 命令還有隔離環境變量,在子腳本中定義的環境變量,即使是全局的環境變量,也不能影響父腳本的環境變量定義。而父腳本中的環境變量可以傳遞到子模塊中。這樣便于模塊化構建腳本程序。
(5) ??? Call 命令不影響當前目錄。
l?????? 從自身的某一行號開始執行:
CALL :<label> [<parameters>]
????????????? 相當于使用自身腳本文件作為子腳本的遞歸調用。
2. ? 如何打開一個子進程來運行命令解釋器?
使用 CMD 命令,執行命令解釋器:
CMD [{/c|/k}] [/s] [/q] [/d] [{/a|/u}] [/t:<f><g>] [/e:{on|off}] [/f:{on|off}] [/v:{on|off}] [<string>]
其中的選項(大小寫不敏感)解釋如下:
(1) ??? [{/c|/k}] [/s]: /k 執行完 <string> 命令后不退出命令解釋器,等待用戶輸入; /c 執行完 <stirng> 命令立即返回;
/s 修飾以上兩者:
如果指定了
/C
或
/K
,命令選項后的命令行其余部分將作為命令行處理;在這種情況下,會使用下列邏輯處理引號字符
("):
1.
如果符合下列所有條件,那么在命令行上的引號字符將被保留
:
-
不帶
/S
命令選項
-
整整兩個引號字符
-
在兩個引號字符之間沒有特殊字符,特殊字符為下列中的一個
:
& < > [ ] { } ^ = ; ! ' + , ` ~ [white space]
-
在兩個引號字符之間有至少一個空白字符
-
在兩個引號字符之間有至少一個可執行文件的名稱。
?2. 否則,老辦法是,看第一個字符是否是一個引號字符,如果是,舍去開頭的字符并刪除命令行上的最后一個引號字符,保留最后一個引號字符之后的文字。
(2) ??? /q: 關閉回顯,默認打開
(3) ??? /d: 關閉在執行命令前自動執行的腳本命令,默認執行,這些命令在注冊表中的一下路徑指定:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun\REG_SZ
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun \REG_EXPAND_SZ
(4)
???
[{/a|/u}]
:
以
ascii
碼或
unicode
標準向管道或者文件輸出
(5)
???
[/t:<f><g>]:
指定前景色和背景色,默認黑地白字:
0
|
Black
|
1
|
Blue
|
2
|
Green
|
3
|
Aqua
|
4
|
Red
|
5
|
Purple
|
6
|
Yellow
|
7
|
White
|
8
|
Gray
|
9
|
Light blue
|
A
|
Light green
|
B
|
Light aqua
|
C
|
Light red
|
D
|
Light purple
|
E
|
Light yellow
|
F
|
Bright white
|
(6)
???
[/e:{on|off}]
:
打開或關閉命令擴展,
默認打開
(7)
???
[/f:{on|off}]
:
打開或關閉文件或目錄名自動完成,自動完成的鍵設置在注冊表中:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\CompletionChar\REG_DWORD
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\PathCompletionChar\REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionChar\REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\PathCompletionChar\REG_DWORD
鍵值格式為:
0xNN, NN
是十六進制的
ASCII
碼。
(8)
???
<string>:
命令字符串
注意:
打開一個子 shell 進程,返回時不影響父 shell 的環境變量
外部的調用 shell 傳遞進來的環境變量(無論在父進程中是局部變量還是全局變量)
在子 shell 中都是全局初始化變量。
[ZT]
命令的延遲擴展:
From: 中國的 DOS 聯盟
在許多可見的官方文檔中,均將使用一對百分號閉合環境變量以完成對其值的替換行為稱之為
“
擴展(
expansion
)
”
,這其實是一個第一方的概念,是從命令解釋器的角度進行稱謂的,而從我們使用者的角度來看,則可以將它看作是引用(
Reference
)、調用(
Call
)或者獲?。?/font>
Get
)。
而命令解釋器是擴展環境變量的行為大致如下:首先讀取命令行的一條完整語句,在進行一些先期的預處理之后,命令被解釋執行之前,會對其中用百分號閉合的字符串進行匹配,如果在環境空間中找到了與字符串相匹配的環境變量,則用其值替換掉原字符串及百分號本身,如果未得到匹配,則用一個空串替換,這個過程就是環境變量的
“
擴展
”
,它仍然屬于命令行的預處理范疇。
而一條
“
完整的語句
”
,在
NT
的命令解釋器
CMD
中被解釋為
“for if else”
等含有語句塊的語句和用
“& | && ||”
等連接起來的復合語句。
因此,當
CMD
讀取
for
語句時,其后用一對圓擴號閉合的所有語句將一同讀取,并完成必要的預處理工作,這其中就包括環境變量的擴展,所以在
for
中的所有語句執行之前,所有的環境變量都已經被替換為
for
之前所設定的值,從而成為一個字符串常量,而不再是變量。無論在
for
中將那些環境變量如何修改,真正受到影響的只是環境變量空間,而非
for
語句內部。
而為了能夠在
for
語句內部感知環境變量的動態變化,
CMD
設計了延遲的環境變量擴展特性,也就是說,當
CMD
讀取了一條完整的語句之后,它不會立即執行變量的擴展行為,而會在某個單條語句執行之前再進行擴展,也就是說,這個擴展行為被
“
延遲
”
了。
延遲環境變量擴展特性在 CMD 中缺省是關閉的,開啟它的方法目前有兩個:一是 CMD /v:on ,它會打開一個新的命令行外殼,在使用 exit 退出這個外殼之前,擴展特性始終有效,常用于命令行環境中;二是 setlocal EnableDelayedExpansion ,它會使環境變量的修改限制到局部空間中,在 endlocal 之后,擴展特性和之前對環境變量的修改將一同消失,常用于批處理語句中。
3. ? 如何調用子進程來執行其他程序(當然也包括 CMD.exe )或者通過文件關聯來打開文件?
Start 命令可以用來執行該操作,利用文件關聯來啟動相應的程序打開文件:
START [/d<path>] [/separate|/shared]
[“<title>”] [/i] [/b] [{/min|/max}] [{/low|/high|/normal|/abovenormal|/belownormal|/realtime}]
[/wait] [/b] <command>
其中選項為:
(1) ??? <title>: 新建窗口的題目
(2) ??? <path>: 初始路徑
(3)
???
[{/min|/max}]
:
啟動窗口大小
(4)
???
[{/low|/high|/normal|/abovenormal|/belownormal|/realtime}]:
制定運行級別
(5)
???
/wait:
父進程等待子進程執行結束,如果子進程啟動的是
GUI
程序,同樣等待。
(6)
???
[/separate|/shared]:
在共享或獨立空間運行
16
位程序
(7)
???
<command>:
要執行的命令行,如果是
CMD
將被
CMDSPEC
環境變量替換,防止從當前目錄執行
CMD
(8)
???
/i:
新環境是傳遞
cmd
的原始環境,而不是當前環境
(9)
???
/b:
見下面說明
說明:
Start 命令打開一個新窗口并啟動子進程執行命令解釋器,在命令解釋器中執行 <command> 。對于非 GUI 程序,執行完畢后不返回主程序,而是等待用戶繼續輸入,直到 exit 。對于 GUI 程序,啟動界面后立即返回,并關閉解釋器窗口(和腳本中的行為不同,在腳本中是等待 GUI 程序退出,繼續執行后續命令)。如果父進程在等待,則直到該 GUI 程序退出,父進程才返回(或者父進程被 Ctrl+C 中止等待,但不影響 GUI 程序的執行)。
但是如果指定 /b 選項, start 并不啟動一個新的窗口和進程,而是在當前窗口執行。這時如果沒有指定 /wait 選項,只有通過 Ctrl+Break 方法中止該程序,而 Ctrl+C 由父進程解釋器處理,因而不能中止該程序,但解釋器啟動的程序可以得到 Ctrl+C 的輸入來自行處理該事件。
Start 命令定義了一些擴展名作為搜索可執行程序的范圍,這些擴展名在 PATHEXT 變量中被定義,一般是:
.COM;.EXE;.BAT;.CMD;
如果給出的是文件名,則利用文件關聯來打開;如果是目錄,則用 explorer.exe 打開。
Start 命令是在系統 ” 啟動 ” 對話框中被用來啟動應用程序。
4. ? 如何退出腳本 ?
可以利用 EXIT 來退出腳本或命令解釋器 :
EXIT [/b] [<n>]
??????? /b 選項打開,表示如果是在執行腳本程序,則退出腳本程序,否則退出命令解釋器。如果沒有指定 /b, 則總是退出命令解釋器。
??????? <n> 是退出代碼,如果只是退出腳本程序,命令解釋器設置 ERRORLEVEL 為 <n>; 如果退出命令解釋器,則進程的退出代碼被設置為 <n> 。 <n> 默認值是 0 ,當腳本執行到末尾,其退出代碼也是 0 。
5. ? 如何理解 Error level ?
Error level 用來表示命令或程序執行結果的狀態, 0 表示正常退出,其它值表示異常退出,一般異常值越大表示錯誤越嚴重,但也可用來表示錯誤的類型。
Error level 可以通過設置環境變量 ERRORLEVEL 來設定:
SET ERRORLEVEL=<n>
也可通過在腳本退出時設定:
EXIT /b <n>
當命令解釋器執行一個可執行程序或內部命令時,獲取該進程的退出代碼作為 Error level 。
在執行 CHOICE 命令時也會改變 errorlevel 的值。
注意: Errorlevel 是整數值(正負均可)。通過設置環境變量,雖然可以將 ERRORLEVEL 設置為非整數值字符串,在使用的時候會自動轉化為 0 。雖然在 EXIT 退出時也可以用字符串作返回值,但 errorlevel 會被命令解釋器自動轉化為 0 。
6. ? 如何在局部范圍內指定命令擴展和變量擴展?
SETLOCAL
[{enableextension | disableextensions}] [{enabledelayedexpansion | disabledelayedexpansion}]
該命令可以嵌套,如果設置成功其中任意一個選項, ERRORLEVEL 變量被設置為 0 ,否則為 1 ,可以用這個來判斷命令解釋器是否具有上述開關功能。