相信,不少小夥伴兒都在命令提示符中執行過 ipconfig
查看 ip
信息。咱們還能夠執行 ping ip
來 ping
對應的 ip
地址,執行 notepad
啓動記事本,執行 explorer
啓動文件管理器…… windows
可是,你好奇過背後的運做機制嗎?爲何輸入幾個簡單的幾個字母就能啓動外部程序,本文試圖經過一系列實驗來挖掘其背後的運做機制。bash
若是你對下面的問題有很明確的答案,本文不是爲你準備的。若是有模糊,拿不許的地方,請耐心讀完。若是以爲有用,請幫忙點個在看,拜謝。測試
一、在命令提示符裏輸入 notepad
,是哪一個位置的記事本被啓動了?跟什麼有關?ui
二、若是同一個目錄下有兩個名爲 bcn
的文件,一個是 bcn.com
, 一個是 bcn.exe
。在命令提示符中輸入 bcn
會執行哪一個?受什麼影響?spa
三、你知道怎麼讓本身的程序能夠直接在命令提示符中被啓動嗎?像執行 ipconfig
那樣。3d
四、若是 PATH
環境變量是空的,會有什麼問題?日誌
五、若是 PATHEXT
變量是空的,會有什麼問題?code
實驗1:在命令提示符中輸入一個不存在的命令(好比,bcn
),使用 process monitor
觀察整個過程。cdn
如咱們所料,找不到。結果以下圖:blog
在觀察 process monitor
捕獲的日誌以前,咱們先查看當前命令提示符的當前路徑( Current Directory
)和 PATH
環境變量的值。
下圖是使用 process monitor
捕獲的事件,已過濾無關信息。
紅色高亮部分是當前路徑相關的事件,黃白相間的部分是 PATH
環境變量相關的事件。
今後能夠比較有信心的猜想:在命令提示符中輸入命令會先在當前路徑下查找,再到 PATH
環境變量指定的路徑依次查找。
實驗2: 添加一個不存在的路徑到 PATH
環境變量中,再次觀察整個過程。
:: 更新 PATH 環境變量set PATH=%PATH%d:\not_existed_folder:: 執行命令bcn複製代碼 |
當前路徑沒變,而對應的 PATH
已經多了一條 d:\not_existed_folder
,以下圖:
下圖是使用 process monitor
捕獲的相關事件(已過濾無關事件)。跟上面的實驗對比,發現只多了黃色高亮部分。
注意對比上圖中黃色和紅色部分。紅色部分對應的路徑是存在的,因此有三條記錄。黃色部分對應的路徑是不存在的,只有一條記錄。能夠雙擊某條記錄,查看對應的調用棧。相信查看過調用棧後,你會和我同樣,對 Operation
這一列有一個新的認識。
實驗3: 把 bcn.exe
放到當前路徑( C:\Users\bcn\Desktop
)下,執行 bcn
。
從上圖可知,啓動的是 C:\Users\bcn\Desktop\bcn.exe
,由於在當前路徑下就找到了對應的程序,因此並無到 PATH
環境變量指示的路徑中查找。
實驗4: 刪除 C:\Users\bcn\Desktop\bcn.exe
,把 bcn.exe
放到 PATH
環境變量中的 c:\windows\
下,再次執行 bcn
。
從上圖可知,啓動的是 C:\Windows\bcn.exe
,在當前路徑下沒找到,而後依次到 PATH
環境變量指示的路徑中查找,在c:\windows\
下找到了對應的程序。
實驗5: 清空 PATH
環境變量,在命令提示符中輸入 ipconfig
,看看是否能正常運行。
結論:
經過以上幾個實驗,咱們知道了在命令提示符中執行一個命令時的查找順序是:當前路徑,PATH
環境變量中指定的路徑(按出現順序進行查找)。
相信有細心的小夥伴兒發現了,在上面的 實驗3
和 實驗4
中,會先查找 bcn.COM
,沒找到才繼續查找的 bcn.exe
。爲何是這種行爲呢?跟什麼有關呢?咱們看下 PATHEXT
環境變量的值,以下圖:
咱們發現 .COM
出如今 .EXE
以前,是否是這個緣由呢?讓咱們作實驗來驗證。
實驗6: 觀察 PATHEXT
是否會影響查找結果。
調整 PATHEXT
的值爲 .BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.EXE;.COM
,若是查找了前面的幾個後綴,而沒查找 .COM
,說明 PATHEXT
會影響查找結果。
set PATHEXT=.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.EXE;.COMbcn複製代碼 |
process monitor
捕獲的事件驗證了咱們的猜想。截圖:
實驗7: 觀察 PATHEXT
時的行爲。
清空 PATHEXT
,再執行 bcn
。
set PATHEXT=bcn複製代碼 |
process monitor
捕獲相關事件以下圖:
有點意外,本來覺得會執行失敗。看來若是 PATHEXT
是空,會使用默認的 PATHEXT
,默認的 PATHEXT
是什麼呢?
實驗8: 觀察默認的PATHEXT
。
重命名 bcn.exe
爲 bcn.xyz
(很重要),而後執行下面的命令:
set PATHEXT=bcn複製代碼 |
process monitor
捕獲相關事件以下圖:
在個人系統(win10 1903
)中,當 PATHEXT
爲空時,默認搜索的擴展名是 .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC;
。其它系統可能有不一樣的行爲,感興趣的小夥伴兒請自行實驗。
實驗9: 當前目錄下同時存在 bcn.com
和 bcn.exe
會執行哪一個?(經過上面的實驗,結論很明顯了)
分別執行下面兩組命令,觀察對比結果:
set PATHEXT=.COM;.EXEbcn複製代碼 |
set PATHEXT=.EXE;.COMbcn複製代碼 |
procmon
捕獲的兩次查找過程對比圖,黃色是設置 .COM
優先的結果,紅色是設置 .EXE
優先的結果。
從結果能夠進一步肯定,優先查找 PATHEXT
中先出現的後綴名。
實驗10:觀察直接執行 bcn.exe
觀察查找過程。
若是命令中帶後綴,那麼查找的時候不會依賴 PATHEXT
,會直接執行給定的命令。
若是你也想本身動手實驗。能夠新建一個工程,並粘貼下面的代碼,編譯生成測試程序。
#include "stdafx.h"#include <windows.h>#include <stdio.h>#include "stdlib.h"int main(int argc, char* argv[]){ char exe_path[MAX_PATH] = { 0 }; ::GetModuleFileNameA(NULL, exe_path, MAX_PATH); printf("%s\n", exe_path); system("pause"); return 0;}複製代碼 |
相信經過上面一系列的實驗,咱們對命令提示符如何執行一個外部命令有了深入的認識。對 PATH
和 PATHEXT
這兩個環境變量的做用,簡單總結以下:
PATH
決定了外部命令所在位置的查找順序,PATHEXT
決定了外部命令的擴展名查找順序。Current Directory
)中查找,若是找不到,纔會到環境變量 PATH
指示的路徑中查找。PATHEXT
指示的後綴順序依次拼接成完整名稱再查找。PATHEXT
中的後綴查找。PATH
環境變量中,位置越靠前,越有可能被執行。PATHEXT
爲空,那麼會使用默認的 PATHEXT
,我機器上的值是 .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC;
。