最近因為需要測試 Linux 環境,除了安裝多個 WSL 實體外,還不斷重新設置新的發行版,因此在這裡紀錄一下過程以及常用的指令。
安裝與運行 Ubuntu 22.04 發行版
從 Microsoft Store 安裝的發行版,同一版本只能存在一個 WSL 實體。想要多個實體就需要使用匯入安裝進行配置。
首先,前往 Ubuntu Cloud Images,下載 ubuntu-22.04-server-cloudimg-amd64-root.tar.xz
,另存到本地路徑 C:\distro
。
安裝 WSL (Ubuntu-test):
1wsl --import Ubuntu-test C:\WSL\Ubuntu-test C:\distro\ubuntu-22.04-server-cloudimg-amd64-root.tar.xz2# 確保 C:\WSL 目錄具有適當的權限,避免因權限問題導致安裝失敗。可以考慮使用 D 盤等其他磁碟。
查看 WSL 清單:
1# 可以簡寫為 `wsl -l -v`2wsl --list --verbose3###4 NAME STATE VERSION5* Ubuntu-22.04 Running 26 Ubuntu-test Stopped 27 [...]
啟動 Ubuntu-test
:
1wsl -d Ubuntu-test2###3root@vince987:/mnt/c/Users/test#
預設使用 root
登入,我們需要設置一個主機名稱和普通使用者,使其運作方式類似一般的 WSL 發行版。
新增普通使用者
當前透過
root
登入 WSL - Ubuntu-test。
(可選) 確保 adduser 指令可以使用:
1apt update && apt install -y adduser
新增一個普通使用者 (myuser
):
1adduser myuser2# 後續跟著指引,填寫密碼和其他資訊3# 建議立即設置一些基本的安全策略,例如更改密碼策略或禁用 root 遠端登入,以防止潛在的安全風險。
將新使用者加入 sudo 群組,授予管理權限:
1usermod -aG sudo myuser
查看使用者權限和群組:
1id myuser2###3uid=1001(myuser) gid=1001(mygroup) groups=1001(mygroup),27(sudo)
查看使用者的家目錄和群組
可以使用以下指令查看所有使用者的家目錄和 shell:
1cat /etc/group2# OR3getent group4###5root:x:0:6daemon:x:1:7bin:x:2:8sys:x:3:9adm:x:4:syslog10[...]11sudo:x:27:myuser12[...]13myuser:x:1000:
說明:
- 第一欄:群組名稱。
- 第二欄:密碼(通常為 x,表示已加密存儲於
/etc/gshadow
)。 - 第三欄:群組 ID(GID)。
- 第四欄:群組成員。
只想列出指定使用者所屬的群組:
1groups myuser2###3myuser : myuser sudo
這表示 myuser
同時屬於群組 myuser
和 sudo
。
查看當前使用者所屬的群組,使用更加簡潔的指令:
1groups2# OR3id -Gn4###5myuser sudo
最後,嘗試切換到 myuser
:
1su myuser2###3myuser@vince987:/mnt/c/Users/test$
記得切換回 root
,繼續後續設定:
1sudo su
設置預設登入使用者
編輯 /etc/wsl.conf
,新增以下內容:
1[user]2default=myuser
如果文件不存在,可以直接使用 echo
一次處理到位:
1echo -e "[user]\ndefault=myuser" > /etc/wsl.conf
回到 Windows 主機,重啟 WSL:
1wsl --shutdown2wsl -d Ubuntu-test3###4myuser@vince987:/mnt/c/Users/test$
啟用 systemd
systemd
是 Ubuntu 預設的初始化系統,建議啟用它。這樣的體驗會更接近 Microsoft Store 安裝的發行版,同時 Docker 的安裝運行也需要它。
首先,測試 systemd
是否可用:
1systemctl --version2###3System has not been booted with systemd as init system (PID 1). Can't operate.4Failed to connect to bus: Host is down
編輯 /etc/wsl.conf
,新增以下內容:
1[boot]2systemd=true
回到 Windows 主機,重啟 WSL:
1wsl --shutdown2wsl -d Ubuntu-test
再次測試 systemd
是否可用:
1systemctl --version2###3systemd 249 (249.11-0ubuntu3.12)4+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY -P11KIT -QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified
設置主機名稱
主機名稱的檔案路徑在 /etc/hostname
,查看當前的主機名稱:
1cat /etc/hostname2###3vince987
方法一:修改 /etc/hostname
和 /etc/hosts
(WSL 不建議使用)
先介紹常規 Linux 發行版的修改方法。
設置新的主機名稱(如 my-ubuntu-wsl
):
1echo "my-ubuntu-wsl" > /etc/hostname2# 如果有開啟 systemd,也可以使用以下指令:3sudo hostnamectl set-hostname my-ubuntu-wsl
記得同步修改 /etc/hosts
:
- 找到以下內容:
1127.0.0.1 localhost2127.0.1.1 vince987 vince987
- 修改成以下內容:
1127.0.0.1 localhost2127.0.1.1 my-ubuntu-wsl my-ubuntu-wsl
/etc/hosts
是一個本地 DNS 查詢文件,用於將主機名稱映射到對應的 IP 地址。如果只修改了主機名稱,但未同步更新/etc/hosts
,系統可能無法正確解析新的主機名稱。
回到 Windows 主機,重啟 WSL:
1wsl --shutdown2wsl -d Ubuntu-test
重新進入 WSL,發現主機名稱又恢復到預設值。
1myuser@vince987:~$
這是因為 WSL 的主機名稱由 Windows 控制生成,並會在 WSL 啟動時重新設置為預設值。
回到 Windows 主機,使用以下指令查詢主機名稱:
1hostname2###3vince987
因此,建議使用第二種方法來修改主機名稱。
方法二:修改 /etc/wsl.conf
(推薦)
編輯 /etc/wsl.conf
,新增以下內容:
1[network]2hostname=my-ubuntu-wsl
回到 Windows 主機,重啟 WSL:
1wsl --shutdown2wsl -d Ubuntu-test
重新進入 WSL,現在主機名稱已經修改成功:
1myuser@my-ubuntu-wsl:~$
查詢 /etc/hosts
的內容:
1[...]2127.0.0.1 localhost3127.0.1.1 my-ubuntu-wsl my-ubuntu-wsl4[...]
設置預設開始路徑
這一步不是必要的,但在某些特殊情境中非常有用,故在此紀錄。
設置 ~/.bashrc
或 ~/.zshrc
我的環境是使用 bash
,直接使用以下指令:
1echo "cd ~" >> ~/.bashrc
重新進入 WSL,可以看到開始路徑在我們指定的位置。
到此,設置算是全部完成。
延伸討論
其實從 Microsoft Store 安裝的發行版,並沒有使用上述方法設置預設開始路徑,而是透過 Windows Terminal 進行設置:
如果是由我們自行匯入配置的 WSL,則設定路徑為 ~
即可:
清理
使用以下指令刪除指定的發行版:
1wsl --unregister Ubuntu-test
然後到 C:\Users\<使用者名稱>\AppData\Local\Packages\
,
找到與已取消註冊的發行版相關的資料夾(例如,名稱包含 CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc),刪除它。
列出 WSL 清單確認:
1wsl -l -v2###3 NAME STATE VERSION4* Ubuntu-22.04 Running 2
刪除發行版對應的殘留資料夾:
1rm C:\WSL\Ubuntu-test
至此,整個設置和清理流程已經完成。