🔥 本文介紹工具已不再推薦使用,建議改用 Windows Terminal (GitHub) 來進行 WSL 操作 🔥
Windows 下的任何命令列工具,都是基於傳統 Windows Console 介面進行互動,你很難想像 Windows Console 的原始碼已經超過 30 年沒有更新過,所以當 WSL 加入 Windows 之後,所遇到的挑戰比你想想的大許多,更新的速度也非常慢,目前也只有 Windows Insider 版本才能體驗新的功能。本篇文章我將分享幾個我曾經遇到過的問題,還有介紹 WSLtty 工具,幫助你徹底解決這些難題。
使用 Windows Console 操作 WSL 通常不會出問題,但在特定情況下,整個 Windows Console 會直接凍結(hang),完全無法輸入輸出,查問題的過程會非常耗時,我個人就遇過很多次,有時真的會氣到不太想再用它。
編碼問題
我有個主機代管的客戶,由於幫客戶管理的 Linux 主機已經使用超過 15 年,過程中升級過幾次,服務基本上都沒出什麼大狀況。不過去年有段時間需要連入主機設定 cronjob 排程,一般來說只要輸入 crontab -e
就可以進入編輯,我用 PuTTY 都沒事,但只要用 WSL 就會 hang 住。
當時這個問題困擾我好幾天,因為我所有管理的 Linux 電腦操作都沒問題,只有客戶的主機會 hang 住,我試圖找出問題發生的主因,後來發現這點根本無解,因為在 Windows Console 的限制下,如果在 WSL 視窗出現 "non-Unicode" 字元,就很有可能會整個畫面 hang 住,但其實程式還在執行,只是不能進行互動而已,最後只能整個 WSL 關閉重開。
像我這個客戶,他們的 cronjob 內容應該包含一些使用 Big5 編碼撰寫的註解,我就只是單純的透過 crontab -l
將內容顯示在畫面上而已,整個 WSL 視窗就會 hang 住,更別說要執行 crontab -e
了!進一步實驗,發現所有用 Big5 編碼的文字檔都有這種情況,實在不勝其擾!如果你將檔案內容的文字編碼改用 UTF-8 的話,所有問題就會自然消失,真的超雷!
光是這個問題,我就覺得 Windows Console 已經完全不能使用了,連正常的工作都不行!
以下我列出幾個跟 WSL 與 Windows Console 相關的網址,大家可以到這邊查問題或反饋問題:
如果可以的話,建議可以改用 WSLtty 或 Cmder 來開啟 WSL 進行操作。
安裝方式
-
透過 Windows 安裝程式
WSLtty 官網有個 Windows 安裝程式,你直接到 Release 頁面下載最新版安裝即可。
-
透過 Chocolatey 自動安裝
choco install wsltty
升級版本
choco upgrade wsltty
-
透過 Scoop 自動安裝
scoop bucket add extras
scoop install wsltty
升級版本
scoop update wsltty
如何啟動
要將 WSL 啟動在 WSLtty 環境下,有以下幾種啟動方式:
-
透過命令列模式啟動 WSLtty 環境
安裝完成後,而 WSLtty 會在這個資料夾建立相對應的批次檔,用以啟動 WSLtty 為主的 Terminal 環境。
Windows 10 內建的 WSL 主要程式路徑位於 %LOCALAPPDATA%\Microsoft\WindowsApps
資料夾,所有相關程式都會置於這個資料夾內。而本文所介紹的 WSLtty 主要程式路徑位於 %LOCALAPPDATA%\wsltty
資料夾下。
-
如果你個人習慣的啟動方式是執行 ubuntu.exe
- 那麼啟動 WSLtty 的批次檔就是
Ubuntu.bat
或 Ubuntu~.bat
-
如果你個人習慣的啟動方式是執行 ubuntu1804.exe
- 那麼啟動 WSLtty 的批次檔就是
Ubuntu-18.04.bat
或 Ubuntu-18.04~.bat
-
如果你個人習慣的啟動方式是執行 wsl
或 bash
的話
請注意:上述的批次檔中,有加上 ~
與沒有 ~
的最大差異,在於:
- 若在
G:\Projects
執行 WSL.bat
預設在 WSL 中會停留在 /mnt/g/Projects
目錄下
- 若在
G:\Projects
執行 WSL~.bat
預設在 WSL 中會停留在 $HOME
目錄下
-
從「開始功能表」(Start Menu) 啟動
安裝完成後,你的開始功能表會多出一個 WSLtty
目錄,裡面有許多捷徑可以點擊啟動,也可以透過搜尋方式啟動。
另外在第一層也會有個 WSL Terminal
捷徑,他會啟動預設的 WSL 安裝。
在開始功能表的 WSLtty
分類下,還有個 configure WSL shortcuts
捷徑,當你從 Microsoft Store 安裝額外的 Linux 發行版本後,可以點擊這個捷徑,他會全自動幫你重新設定相對應的批次檔與捷徑,方便你日後啟動 WSLtty 終端機。
-
從「檔案總管」按右鍵選擇 WSL Terminal
啟動
在開始功能表的 WSLtty
分類下,也有個 add default to context menu
與 add to context menu
捷徑。如果執行 add default to context menu
的話,他會幫你自動註冊機碼,讓你之後在檔案總管中可以按滑鼠右鍵選擇 WSL Terminal
啟動終端機。選擇 add to context menu
的話,就會自動把所有安裝的 WSL 版本(Distro)全部加到右鍵選單中(Context Menu)。
執行 remove from context menu
就可以解除安裝。
如果想把 Ubuntu 18.04
的 WSL 設定為預設的話,你要手動修改 %LOCALAPPDATA%\wsltty\config-distros.sh
檔案,修改 158 行,將 minttyargs='--WSL --configdir="'"$configdir"'"'
修改為 minttyargs='--WSL="Ubuntu-18.04" --configdir="'"$configdir"'"'
即可。
再者,如果你想調整啟動 WSL Terminal
的快捷鍵,可以修改 HKEY_CURRENT_USER\Software\Classes\Directory\Background\shell\WSL_Terminal
機碼內的 (預設值)
字串內容,將 WSL Terminal
修改為 W&SL Terminal
就會有 S
快捷鍵可以按。使用方式將會是:
- 先透過檔案總管瀏覽到特定目錄
- 在畫面空白處按下滑鼠右鍵並按下
s
按鍵,這樣就會自動啟動 WSL Terminal
主要設定檔位置
由於 WSLtty 是 Mintty 的一個子專案,所以他的所有設定都可以參照 Mintty Manual 的說明,你也可以從官網得知 Mintty 真正想解決的問題為何。
以下是安裝完 WSLtty 之後預設的 %LOCALAPPDATA%\wsltty\Ubuntu-18.04~.bat
批次檔內容,你可以發現啟動 WSLtty 其實就是啟動 mintty.exe
程式而已,只是特別加上 --WSL
參數指定 WSL 的特定 Linux 發行版本執行:
%LOCALAPPDATA%\wsltty\bin\mintty.exe -i "%LOCALAPPDATA%\wsltty\wsl.ico" --WSL="Ubuntu-18.04" --configdir="%APPDATA%\wsltty" -~
上述的 --configdir
就是指定 Mintty 的設定檔載入路徑。
啟動 WSLtty 的過程中,可以參考以下幾個路徑,這是載入設定檔的優先順序,越上面優先權越高:
-
直接使用 -c
指定設定檔路徑 (預設 wsltty 安裝時不是用這個)
-
直接使用 --configdir
指定設定檔所在資料夾,它會去找這個資料夾下的 config
檔案
WSLtty 預設的主要設定檔位於 %APPDATA%\wsltty\config
-
自動搜尋 %HOME%\.minttyrc
檔案 (不建議使用這個檔案進行設定)
-
自動搜尋 %HOME%\.config\mintty\config
檔案 (不建議使用這個檔案進行設定)
-
自動搜尋 %APPDATA%\mintty\config
檔案
-
自動搜尋 %LOCALAPPDATA%\wsltty\etc\minttyrc
檔案 (不建議使用這個檔案進行設定)
進階應用
要透過 WSLtty 啟動 WSL (Ubuntu 18.04) 除了用預設的批次檔外,還可以透過以下命令進行調整啟動參數:
-
直接呼叫啟動,進入預設 shell 環境,並停留在 $HOME
目錄下 (-~
)
%LOCALAPPDATA%\wsltty\bin\mintty.exe --WSL="Ubuntu-18.04" --configdir="%AppData%\wsltty" -~
-
直接呼叫啟動,進入預設 shell 環境,並設定終端機顯示文字以 Big5 字集為主 (預設為 UTF-8
字集)
%LOCALAPPDATA%\wsltty\bin\mintty.exe --WSL="Ubuntu-18.04" --configdir="%APPDATA%\wsltty" -o Charset=Big5
-
直接呼叫啟動,進入指定 shell 環境 (bash
)
%LOCALAPPDATA%\wsltty\bin\mintty.exe --WSL="Ubuntu-18.04" --configdir="%APPDATA%\wsltty" /bin/bash -l
像是上述指令都可以封裝成一個個批次檔,降低進入 WSL 的難度。預設 WSLtty 提供的批次檔都會複製一份到 %LOCALAPPDATA%\Microsoft\WindowsApps
資料夾,你也可以直接修改這裡的批次檔內容。
以往我們要直接啟動 WSL 並執行程式的方式有好多種,例如:
wsl ls -laF ~
bash -c "ls -laF ~"
ubuntu run ls -laF ~
ubuntu run sh -c 'ls -laF ~'
如果想要透過 WSLtty 啟動 WSL (Ubuntu 18.04) 並自動執行腳本後退出,可以透過以下命令:
-
直接呼叫啟動,並執行指定程式後關閉退出
建議將批次檔內容加上 %1 %2 %3 %4 %5 %6 %7 %8 %9
參數,到執行 mintty.exe
這行的最後面,例如:
%LOCALAPPDATA%\wsltty\bin\mintty.exe -i "%LOCALAPPDATA%\wsltty\wsl.ico" --WSL= --configdir="%APPDATA%\wsltty" %1 %2 %3 %4 %5 %6 %7 %8 %9
如此一來就可以徹底簡化命令列輸入!
-
列出 $HOME
目錄所有檔案
wsl.bat ls -laF ~
-
列出 $HOME
目錄所有檔案並將檔案輸出到 Windows 的當前目錄
由於用到 >
符號,所以必須透過 sh -c
傳入執行
wsl.bat sh -c "ls -laFR ~ > ./HOME_File_List.txt"
-
查看 /var/log/dpkg.log
檔案變更
wsl.bat tail -f /var/log/dpkg.log
-
透過 WSL 使用 SSH 連線至遠端電腦
wsl.bat ssh 172.14.19.3
-
透過 WSL 使用 SSH 執行遠端命令
wsl.bat ssh 172.14.19.3 tail -f /var/log/syslog
常用快速鍵
有在玩 Linux 的人,應該各個都是快速鍵的好手,所以用了 WSLtty 之後,哪能不記一些好用的快速鍵呢!
底下的快速鍵中,請記得先開啟 Ctrl+Shift+字母
快捷鍵才能使用相關快速鍵,預設這個快速鍵組合是關閉的:
相關連結