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