打破指令和圖形界面的次元壁!用捷徑圖示執行指令

這篇文章來自 命令列從入門到出門 系列。

用例:某個檔案希望用不是預設的程式打開,或是想把一拖拉庫的檔案丟給某個程式。

Windows 下的圖形界面,有個非常好用的功能,就是拖動一個或者一拖拉庫檔案或者資料夾到一個程式的圖示上,可以用程式打開這些檔案。

這個方法可以適用在一些特殊的檔案,不限但包括 .exe 執行檔、 .lnk 捷徑 和 Batch .bat 批次檔上。 但絕大部分的檔案可能都不行,例如 Python 的 .py 和 PowerShell 的 .ps1

TL;DR: 這類 Script 並非可執行檔,Windows 不會自動以解譯器打開, 且 PowerShell 的執行政策(Execution Policy)限制了 .ps1 的直接執行。

最簡單的用法例如,想要用記事本編輯一個文字檔,但沒有它沒有綁定擴展名不能預設用記事本開啟, 就可以把這個檔案直接拖動到記事本的圖示上,就可以直接用記事本打開它了。

這個功能的本質是,將檔案或資料夾拖動到程式的圖示,把這他們的路徑以「參數」的方式,傳遞給拖拽的目標。 例如說,你把檔案 1.txt2.txt 拖動到 code.exe 程式上,實際上會執行 code.exe 1.txt 2.txt

這個功能根本就是打破指令和圖形界面的次元壁:既能享受圖形界面的直覺,又能享受指令列的自動化。

但,有時候我們寫了一個 PowerShell 的 shell script, 或是 Python 程式懶得編譯成 .exe 執行檔(Do not try it at home,超級麻煩),我們還是希望可以使用這個便利的功能。 以 Python 為例,我們就可以用批次檔寫一個「傳送門」:

@ECHO OFF
python -u ./random_script.py %*
@PAUSE

這個批次檔的意思是, 先用 @ECHO OFF 關閉多餘的 Prompt 輸出。 再用 Python 執行 script,並把參數傳遞進去。這裡的 %* 就是批次檔所得到的「所有參數」。 但通常這個批次檔執行完程式後,發現自己沒啥可做了就會直接退出,然後終端界面就會像您的未來一樣轉瞬即逝, 所以最後我們加上 @PAUSE 暫停看看程式的輸出。

在批次檔中,變數 %* 的意思是批次檔所得到的「所有參數」, 還可以展開來 %0 表示批次檔自己所在的位置、%1 表示第一個參數、%2 表示第二個參數、依此類推。 變數 %* 不包括 %0。 這因為電腦中通常數數是從 0 開始,而第〇個參數通常表示程式自己的路徑。 還可以用一些前綴來修飾這些變數,例如 %~dp0 表示「批次檔當前所在的資料夾路徑且去掉引號」。 可以通過 CALL /?官方文檔 查看他的用法。

例如說,你把檔案 1.txt2.txt 拖動到這個批次檔上, 實際上批次檔會執行 python -u ./random_script.py 1.txt 2.txt。 (過程是:〔檔案〕->〔批次檔〕->〔程式〕)

所以 Python script 也可以是一種 shell script,不再需要 Batch 黑魔法詠唱一般的文法。

甚至,我們可以給這個批次檔「傳送門」建立一個捷徑,設定一個圖標,捷徑也會把拖動到它上面的檔案和資料夾以參數的方式傳遞給其目標, 比如我們寫好的「傳送門」批次檔,這個批次檔在呼叫程式並且再把參數傳遞過去(過程是:〔檔案〕->〔捷徑〕->〔批次檔〕->〔程式〕)。 這樣就可以把任何檔案拖進這個捷徑,就會自動傳遞給你的程式處理。

聰明的你一定能想到,誒那我能不能跳過批次檔,直接用捷徑呼叫程式呢?(過程是:〔檔案〕->〔捷徑〕->〔程式〕) 當然不是不行,但在我的測試中,這樣會比較容易遇到空格和引號的跳脫問題,而且沒有批次檔方案靈活,只好作罷。

這樣,我們用幾行批次指令,把 CLI 工具偷渡到了圖形界面裡,打破了兩者的界線,開啟了指令和圖形界面之間的「傳送門」。