Windows10內置Linux子系統初體驗

WSL

前言


前段時間,機子上的win10又偷偷摸摸升級到了一週年正式版,比較無奈。不過之前聽聞這個版本已經支持內置的linux子系統,於是就懷着好奇心試玩了一把。雖然期間遇到了很多問題,但總體來說這個子系統體驗還不錯,在這裏就分享一些關鍵步驟和遇到的問題,剩下的大家自己折騰吧。。

啓用linux子系統


設置(16215版之後不再需要開發人員模式)
Windows功能
安裝ing...
  1. 系統升級到一週年正式版及以上(1607)

  2. 依次在 設置 - 更新與安全 - 針對開發人員 選項中,啓用"開發人員模式"

  3. 在資源管理器中打開 控制面板\所有控制面板項\程序和功能 , 打開 啓用或關閉 Windows功能 , 勾選 適用於Linux的Windows子系統(Beta)

  4. 重啓電腦

  5. 命令行運行 lxrun /install /y 開始安裝
    安裝速度取決於網絡情況,下載的文件在 %localappdata%\lxss 目錄下 lxss.tar.gz (181M),解壓後大概500M, rootfs 目錄即爲子系統根目錄。

  6. 命令行運行 bash 進入Ubuntu
    默認使用的 root 帳號登錄,通過指令 passwd 設置密碼。

  • 注:本文腳本均在root帳號下操作,因此建議使用root帳號
  1. 畢竟愛折騰,難免會把子系統環境(lxss目錄)玩壞掉,因此幹正事前最好先備份下以便快速還原。注意,不要直接右鍵複製或者打包,可能會導致文件權限丟失的。
    xcopy %localappdata%\lxss %localappdata%\lxss.bak /E
  2. 當然,如果你比較任性也可以不執行上一步的備份操作,通過命令行運行 lxrun /uninstall /full 輕鬆卸載子系統,重複上面的步驟即可重裝,不過要注意下載速度時好時壞哦。

通過上面的步驟,已經啓用了win10自帶的linux子系統(WSL),感覺逼格提升了不少。當然,怎麼能滿足於此呢,接下來就要做一些環境的配置和進一步的挖掘。

更換數據源(參考)


Ubuntu下我們可以通過 apt-get 命令 很方便的安裝/卸載軟件,由於默認的軟件包倉庫是位於國外的,安裝軟件的時候就可能遇到各種網絡問題或者下載到的一些資源不完整,因此就需要切換數據源爲國內的鏡像站點來改善。

# 1.備份原來的數據源配置文件
cp /etc/apt/sources.list /etc/apt/sources.list_backup
# 2.編輯數據源配置文件
vi /etc/apt/sources.list

在這裏我使用的是阿里雲的數據源:

deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
# 3.更新配置
apt-get update

注:14986版之後更新了內核,第三方的鏡像站可能找不到軟件包資源,需要切換回官方的源。經測試中科大的源可用

deb https://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse

與 Windows 通訊


目前子系統與 Windows 之間通過以下兩種方式進行通訊

  1. 通過 tcp 協議進行通訊(簡單點說就是用網絡,端口都是通的)
  2. 通過 /mnt/【盤符】/目錄 的方式訪問Windows目錄

試過在Windows的資源管理器中直接對子系統環境目錄下的文件所做的修改不能被子系統所識別,因此需要在bash下進行操作。

安裝 zsh


目前常用的 Linux 系統和 OS X 系統的默認 Shell 都是 bash,但是真正強大的 Shell 是深藏不露的 zsh, 這貨絕對是馬車中的跑車,跑車中的飛行車,史稱『終極 Shell』,但是由於配置過於複雜,所以初期無人問津,很多人跑過來看看 zsh 的配置指南,什麼都不說轉身就走了。直到有一天,國外有個窮極無聊的程序員開發出了一個能夠讓你快速上手的zsh項目,叫做「oh my zsh」,Github 網址是:https://github.com/robbyrussell/oh-my-zsh。這玩意就像「X天叫你學會 C++」系列,可以讓你神功速成,而且是真的。

zsh就是一款強大的虛擬終端,網上也都推薦使用 oh my zsh 來管理配置 , 不過對我來說還是不夠傻瓜。於是,參考一篇文章使用 zsh 的包管理器:antigen 來管理所有功能,文章中還給了現成的配置。

  • 安裝 zsh
sudo apt-get -y install zsh
  • 設置終端的 shell 環境默認爲 zsh,輸入以下命令(需要重啓)
# 加 sudo 是修改 root 帳號的默認 shell
chsh -s `which zsh`
  • 如果上面命令無效,修改 ~/.bashrc 在開頭輸入:
if [ -t 1 ]; then
    exec zsh
fi
  • 安裝 antigen
curl -L git.io/antigen > antigen.zsh

# 修改配置 ~/.zshrc(如果切換帳號後無法使用 zsh 則把該用戶的配置文件再配一遍)
curl -L https://raw.githubusercontent.com/skywind3000/vim/master/etc/zshrc.zsh > ~/.zshrc

# 修改主題, 參考:https://github.com/robbyrussell/oh-my-zsh/wiki/themes
# 如果需要主題一直生效需要添加到 ~/.zshrc 中
antigen theme ys

# 配置修改完重新執行 zsh
  • 如果出現警告:zsh compinit: insecure directories, run compaudit for list.
chmod -R 755 ~/.antigen

安裝 autojump (用法參考)


autojump 是一個命令行工具,它允許你可以直接跳轉到你喜愛的目錄,而不受當前所在目錄的限制。意思就是可以讓你更快地切換目錄,而不用頻繁地使用 cd/tab 等命令。

  • 安裝
sudo apt-get install autojump
  • zsh 下運行報錯
$ autojump
Please source the correct autojump file in your shell's
startup file. For more information, please reinstall autojump
and read the post installation instructions.

參照文章 Mac終端增強技能終極 Shell 找到解決辦法:

~/.zshrc 中安裝插件 brew install autojump 再重新進入 zsh

由於本文使用 antigen 作爲 zsh 的包管理器,所以實際操作是在 ~/.zshrc 中添加 antigen bundle autojump

使用 bash 客戶端軟件 cmder (參考)


Windows 自帶的命令提示符 cmd 並不是很好用(文本選中、複製粘貼等等操作),在這裏使用 cmder 作爲替代品,體驗效果很好。去 cmder 官網下載 mini版(完整版附帶了模擬的bash環境,由於已經安裝 linux 子系統,就不再需要了)的解壓即可使用。

  • 設置啓動 cmder 時直接運行 bash:
1. 進入 "Settings > Startup",
2. 選擇 "Startup options > Command line",輸入 "bash -cur_console:p"
啓動直接運行bash
  • 通過軟件底部的加號按鈕新開標籤頁並進入 bash
1. 進入 "Settings > Startup > Tasks",
2. 選擇 "bash::bash",將指令修改爲 'cmd /c "bash" -cur_console:p -new_console:d:%USERPROFILE%'
新標籤頁
  • 設置配色主題
1. 進入 "Settings > Features > Colors",
2. "Schemes" 項下拉選擇 "<ubuntu>"

小貼士:將 cmder 目錄添加到環境變量 path 中或者複製快捷方式到 "C:\Windows\System32" 目錄下,就可通過 win + R 快捷鍵快速打開了

運行圖形界面程序(參考)


什麼!linux 不是就這麼個黑白界面的窗口嗎?是的,你沒看錯,就是圖形界面,這裏用到的是 Xserver 這個東東,至於原理什麼的各位自行度娘吧。

Xming
  1. 安裝Xming 下載地址

  2. 安裝完直接打開 Xming 即可

  3. 安裝一個 firefox 測試
    apt-get install firefox

  4. 運行(在程序指令前加上"DISPLAY=:0 ")
    DISPLAY=:0 firefox

  5. 簡化配置
    每次運行程序都要輸入 DISPLAY=:0 挺累的,執行下列指令後重啓bash即可省去這個步驟
    echo "export DISPLAY=:0.0" >> ~/.bashrc

PS:很多小夥伴反映說打開Xming沒反應,這是正常現象 ( 詳見評論區33樓 )。Xming是一個在後臺運行的服務,在任務欄顯示一個 X 的小圖標即表示啓動成功,無需其他操作了。要想看到畫面,需要在wsl或其他遠程Linux機器上使用 DISPLAY=:0 命令啓動帶圖形界面的程序。在這裏簡單分析下我理解的原理:1. Xming 啓動 Xserver服務用於監聽;2. wsl啓動程序後把界面數據發送給 Xserver;3. Xserver 接收到數據進行繪製,於是在win下就看到了圖形界面。還有困惑的話請移步至下方的 vnc 版塊,比Xming效果要好,類似與 win 下 遠程桌面連接 的效果。

Sublime Text 3 安裝


既然都可以運行圖形界面了,編輯器也要換成可視化的,畢竟vim還是不太適合我。

cd /
# 下載
wget https://download.sublimetext.com/sublime-text_build-3126_amd64.deb
# 安裝
dpkg -i sublime-text_build-3126_amd64.deb
# 運行
subl
什麼鬼,報錯了!

應該是少了什麼依賴包,嗯,安裝下搞定。

apt-get -y install libgtk2.0-0

啓動 xfce 桌面環境(參考)


圖形界面程序都能運行了,不試試ubuntu的桌面環境怎麼能甘心,於是又是噼裏啪啦一頓搜索。一開始參照這篇國外的教程折騰了許久,每次運行總是報一個composite的插件沒加載進來,各種軟件包安裝一通還是不行,後來實在失去耐心就放棄了這條路。後來看到好像有人成功運行了xfce,但沒有具體步驟,只能自己一頓摸索,結果還真誤打誤撞成功了。

# 1.安裝xfce4
apt-get install xfce4
# 2.安裝xubuntu桌面及附帶應用
apt-get install xubuntu-desktop
# 3.啓動
xfce4-session
啓動報錯了

解決辦法:(參考

sed -i 's$<listen>.*</listen>$<listen>tcp:host=localhost,port=0</listen>$' /etc/dbus-1/session.conf

再次嘗試打開,現在可以看到Xming打開了三個窗口,分別是桌面、任務欄、菜單欄。逼格是提升了不少,不過確實很卡。

xfce4

使用 VNC 進行遠程桌面控制(安裝方法)


感謝 @lizr_4bf0 的提示,使用 VNC 來代替 Xming 以解決 Xming 下很卡的問題。

1. wsl 下安裝 vnc4server
apt-get install vnc4server
2. wsl 下啓動 vncserver ( 安裝後首次啓動需要設置訪問密碼 )
vncserver
3. 在 win10 的 VNC Viewer 中訪問 127.0.0.1:1

注:如果 VNC Viewer 連接報錯請參考

4. VNC Viewer 中只顯示一個終端窗口的問題
# 修改xstartup, 將 x-window-manager 替換爲剛纔安裝的 xfce4-session
sed -i 's$x-window-manager$xfce4-session$' ~/.vnc/xstartup
# 重啓 vncserver
vncserver -kill :1
vncserver :1
5. 分辨率設置
# 先關閉
vncserver -kill :1
# 再啓動並設置分辨率(注意是小寫的x)
vncserver -geometry 1366x768 :1

在子系統上運行nginx


因工作項目中用到了 ssi 技術,而已經windows上已經編譯好的 nginx 是不支持相對路徑引用的(需要修改源碼重新編譯),只能委屈求全用着 Apache 。不過既然現在都能跑linux了,那就試試在linux上運行 nginx,然後在windows上進行調用。

1. 通過apt-get方式安裝
sudo apt-get install nginx
# 啓動報錯了:
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
# 80端口實際沒被佔用,那應該就是ipv6的問題,將其禁用: 
vim /etc/nginx/sites-available/default
# 找到default_server ipv6only=on;註釋掉
# 再次啓動沒報錯,不過瀏覽器無法訪問,80端口也沒被使用,查看error.log
cat /var/log/nginx/error.log
# 看到錯誤信息:
ioctl(FIOASYNC) failed while spawning "worker process" (22: Invalid argument)
# 解決方法:禁用master進程模式
sed -i '1 a\master_process off;' /etc/nginx/nginx.conf

再次啓動,終於沒報錯了,Windows中打開瀏覽器訪問127.0.0.1,還真的實驗成功了,不過nginx版本有點老,是1.4.6的。

2. 通過編譯源碼的方式安裝
# 1.安裝依賴包
apt-get -y install build-essential autoconf libtool libxml2-dev openssl libcurl4-openssl-dev libbz2-dev libjpeg-dev libpng12-dev libfreetype6-dev libldap2-dev libmcrypt-dev libmysqlclient-dev libxslt1-dev libxt-dev libpcre3-dev libreadline-dev
# 2.下載源碼
wget http://tengine.taobao.org/download/tengine-2.1.1.tar.gz
# 3.解壓
tar -zxvf tengine-2.1.1.tar.gz
# 4.進入目錄
cd tengine-2.1.1
# 修改源碼...
# 5.配置
./configure --prefix=/usr/anyesu/nginx
# 6.編譯&安裝
make && make install
# 7.修改配置文件
sed -i '1 a\master_process off;' /usr/anyesu/nginx/conf/nginx.conf
# 8.啓動
/usr/anyesu/sbin/nginx

上面的步驟,我試了兩臺電腦,其中一臺報錯:

nginx: [emerg] invalid port in resolver "fec0:0:0:ffff::1" in /usr/anyesu/nginx/conf/nginx.conf:123

/etc/resolv.conf

出現的 fec0:0:0:ffff::1 是個什麼鬼,度娘了一番,貌似是dsn,打開dns配置文件 /etc/resolv.conf 果然發現了這東西,應該是Windows下只分配了1個dns,所以linux就給了這麼兩個默認值的吧。將它們註釋掉,重新啓動nginx,成功運行 Tengine/2.1.1

注意,每次重啓bash都會重置dns配置的

啓用ssh(參考)


本地可以通過命令行打開bash,如果要遠程訪問(如同訪問線上服務器一樣),那麼就需要啓用ssh。

# 1.安裝ssh(一般不需要這步)
apt-get install openssh-server
# 2.修改配置文件
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
vim /etc/ssh/sshd_config
#=======(修改以下選項內容)=========#
# Port 23(22端口已被佔用)        #
# (取消註釋)ListenAddress 0.0.0.0 #
# UsePrivilegeSeparation no      #
# PermitRootLogin yes            #
# (註釋)StrictModes yes         #
# PasswordAuthentication yes     #
#================================#
# 3.啓動ssh
service ssh start
# 4.如果提示“sshd error: could not load host key”,則用下面的命令重新生成
rm /etc/ssh/ssh*key
dpkg-reconfigure openssh-server

使用終端工具訪問,這裏我用的是 WinSCP + PuTTY

WinSCP
PuTTY

WSL開機啓動


任務管理器

打開任務管理器我們可以發現,在運行子系統的時候,後臺其實有一個bash的進程在運行,我們每開一個命令行窗口就會多一個 bash.exe,如果我們把所有的 bash.exe 都關閉則這個bash進程就關閉了(相當於是子系統關機了),跟着之前在子系統中打開的程序如nginx、sshd等也隨之關閉了。爲了讓linux程序能夠在後臺繼續運行,這裏通過 vbs 腳本在後臺打開一個 bash.exe 來保證bash進程一直開着。當然,還可以通過Windows的計劃任務實現開機啓動WSL並打開其中的程序。

# 1.新建開機啓動腳本
vim /usr/anyesu/boot.sh
# 2.編輯
#================================================================
# #!/bin/sh
# /usr/anyesu/nginx/sbin/nginx
# service ssh start
# $SHELL  #這句很重要,掛起當前腳本進程,進而維持base.exe一直打開
#================================================================
# 3.設置權限
chmod 777 /usr/anyesu/boot.sh
# 4.創建vbs腳本(D:\linux\wsl.vbs)
#==========================================
# Set ws = CreateObject("Wscript.Shell") 
# ws.run "bash /usr/anyesu/boot.sh",vbhide
#==========================================
# 5.創建計劃任務
計劃任務
創建基本任務
設置任務名稱
設置任務觸發條件——用戶登錄
設置任務操作——啓動
設置任務操作——運行vbs腳本
運行計劃任務

關於Linux發行版本


# 打開cmd,進入bash
bash
cd /
# 下載openSUSE
wget -O openSUSE-42.2.tar.xz https://github.com/openSUSE/docker-containers-build/blob/openSUSE-42.2/docker/openSUSE-42.2.tar.xz?raw=true
# 解壓
xz -d /openSUSE-42.2.tar.xz
mkdir rootfs
tar -C rootfs -xvf openSUSE-42.2.tar
# 退出bash,返回cmd
exit
# 進入子系統所在路徑
cd %localappdata%\lxss
# 備份ubuntu用戶空間(看下任務管理器中bash是不是徹底關閉了)
rename rootfs rootfs.ubuntu
# 使用openSUSE用戶空間替換默認用戶空間
move rootfs.ubuntu\rootfs rootfs
# 設置默認登錄用戶
lxrun /setdefaultuser root
# 重新進入bash
bash
#查看發行版本
cat /etc/issue

官方資料


2017-11-21追加


最近系統又被強更到了1709(16299.64),發現幾點變化做個記錄:

  1. ping命令已經可以正常使用了
  2. nginx的master模式也能正常使用不會報錯了
  3. 發現nginx、ssh之類的,能正常啓動不報錯但怎麼也無法綁定端口。後來查了github上的 issues 發現是wegame(原tgp)的鍋,原因是使用了一個win10上已失效的特性,wegame的開發表示會盡快修復。臨時解決辦法:刪除文件 %systemroot%\system32\drivers\QMTgpNetflow764.sys 後重啓bash,如無法刪除先關閉應用或卸載再重裝wegame(最好重啓電腦),重裝後先刪除 QMTgpNetflow764.sys 再運行wegame。
  4. 內核升級爲 4.4.0-43-Microsoft 了, 帶上了微軟的標記,推測是這個原因導致很多軟件包無法正常安裝了。後來發現應該是阿里雲的數據源未同步的原因,加上 ubuntu 自帶的源 ( 即文中最初備份的內容 ) 即可解決。

2017-11-30追加


應用商店

目前 ( 1709 版本 16299.64 ) 已經可以在商店中搜索安裝多個不同版本的子系統了,根路徑爲 %localappdata%\Packages\【根據子系統名找到對應的應用文件夾】\LocalState\rootfs 。同時還新增了兩個命令行工具: wsl.exewslconfig.exe

其中 wsl.exe 應該等價於 bash.exe , 兩者之間的細微差別暫時還沒發現。至於 wslconfig.exe 的作用主要爲(參考):

1. 查看安裝所有已安裝的子系統: wslconfig /l

適用於 Linux 的 Windows 子系統:
Ubuntu (默認)
Legacy

其中 Ubuntu 是商店中下載的版本,Legacy 是按老方法安裝的默認wsl。

2. 切換bash.exe默認使用的子系統: wslconfig /s <DistributionName>
其中 <DistributionName> 替換爲 UbuntuLegacy , 或者其他已安裝的子系統。

3. 卸載已安裝的子系統: wslconfig /u <DistributionName>
同上替換 <DistributionName> 。經測試發現,此 "卸載" 並不會卸載商店中安裝的 Ubuntu 應用, 即再次執行該應用又會重新安裝了。

寫在最後


WSL折騰完有一段時間了,只是一直沒時間記錄下來(也許是懶吧)。在此之前,由於工作需要,偶爾兼職運維的角色,折騰下服務器什麼的,就很業餘的學習了一些linux指令。以前裝過vmware,體驗不是很好就不想裝了,所以寫shell腳本、編譯源碼什麼的都是在公司測試服務器上練習的,現在有了WSL之後就可以在自己本地練習了(肆意折騰,哈哈哈)。使用方面,體驗和使用終端工具連接遠程服務器是差不多的;性能方面,子系統(bash進程)本身是不佔多少內存的,啓動程序幾乎相當於啓動Windows程序了,不顯示圖形界面內存都佔用比較小,肯定優於"印象中的虛擬機"。總的來說,WSL還是比較值得推薦去折騰的,也比較適合新手學習linux,雖然我也只是個小白⊙﹏⊙



作者:anyesu
鏈接:https://www.jianshu.com/p/bc38ed12da1d
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章