Bash on Ubuntu on Windows 安裝、移除與使用教學及效能測試

久違的技術教學系列!隨著電腦達人養成計畫第四章的完結,在第五章開始之前有一段時間會以其他主題的文章為主 (畢竟已經好一陣子都是更新連載系列文了嘛),這篇要談的是當初宣布時讓站長的幾個同學感到很興奮 (雖然我不太懂為什麼) 的 Bash on Ubuntu on Windows (很拗口吧?這是微軟宣布時用的名稱,其實真正的重點是「適用於 Linux 的 Windows 子系統」,在 Windows 上能夠原生執行 Ubuntu 的 Bash 就是這功能的傑作,能跑的當然不只是 Bash)。

ADK9856

這項功能是幹嘛用的?

簡單來說,微軟與 Canonical (就是發展 Ubuntu 的公司) 合作在 Windows 核心深處植入了一套符合 Linux 系統規範的 System Call (系統呼叫),並且以 Ubuntu 為基礎修改了一套可以運作在 Windows 中的 Linux 「子系統」(實際上是一套簡化版本的 Ubuntu 14.04 LTS),由於是直接深植在 Windows 作業系統核心裏頭的,因此比起我們平常使用的 Virtualization (虛擬化) 還要更加接近硬體本身直接執行 (微軟的說法是,跟直接用硬體執行幾乎是一樣的)。

至於這東西的由來呢,微軟的說法是因為在 Windows 10 公眾預覽計畫中有不少人反映希望微軟能改進命令提示字元的功能甚至是引入在 Linux 上的命令列工具。

另一方面大概是受新 CEO 政策的影響吧?微軟最近似乎變得挺傾向於跟其他陣營融合與進行一些以往我們認為不可能發生的嘗試 (不過這樣做效果好不好就見仁見智了),加上有許多開源計畫都是奠基於 Linux/Unix 上,又加上自家先前搞了個已經被擱置的 Project Astoria (本來是打算把 Android App 用原生的方式移植到自家的 Windows 10 Mobile 上以解決當前 Windows 市集上 App 數量不多的問題),這計畫或許有留下一些遺產吧?(雖然未經證實,但挺合理的,畢竟 Android 本質上也是 Linux)。

微軟本身非常強調這項技術與傳統我們認知的虛擬機器是一點關係也沒有的,如果你看不太懂甚麼子系統、System Call 之類的東西的話,下面這張示意圖或許能夠幫助你理解,你可以將 System Call 想像為作業系統核心 (Kernel) 所提供的功能,而核心之外的程式都是在作業系統核心的基礎上執行的,它們會去使用 (呼叫) 作業系統核心提供的 System Call 來命令電腦的硬體元件做事。

而 Windows Subsystem for Linux 的原理就是在 Windows 的作業系統核心裡面設計一個叫做 WSL 的模組,這個模組會向 Linux 程式提供它們會需要的 System Call (與 Windows 程式所使用的 System Call 格式不同,無法直接相容,這也是雖然都基於 x86 架構,但 Linux 程式並無法在 Windows 系統下執行的主因),因此 Linux 程式就可以靠著這個模組 (由 Windows 系統核心代理) 來直接向硬體元件下達指示了,此外,由於這個模組是設計在原生執行中的 Windows 作業系統核心裡,因此運作於其上的 Linux 看起來就也像是原生執行般,理論上性能會比 VM 好很多。

如果要說得更簡單一些的話,就是 Windows 系統核心這層之上與 Linux 應用程式這層之下之間,多了一層像是翻譯機的東西,讓 Linux 應用程式發出的訊號能夠轉介給 Windows 系統核心再直接交給硬體處理,硬體處理完畢的訊號也能透過這層翻譯機來將結果翻譯成 Linux 應用程式看得懂的格式。

而除了程式本身的執行能力之外,另一個需要考慮的問題是檔案系統的相容性。我們知道 NTFS 與 Linux 慣用的 ext 系列檔案系統是不相容的,因此微軟為此生出了兩款「模擬」檔案系統,其中第一套是 VolFS,使用與標準 Linux 完全相容的檔案系統,用來存放 Linux 子系統本身的檔案以確保系統正常運作,權限管理也是使用 Linux 的那套 chmod 跟 chown 來處理 (值得注意的是,每個使用者存取 WSL 的時候,設定與 VolFS 內容的變更、Linux 子系統的帳號密碼系統都是獨立且互不影響的);第二套則是 DriveFS,用於讓 Linux 子系統能夠直接存取以 NTFS 或其他 Windows 檔案系統為基礎的磁碟區,權限管理則以 Windows 系統為準,僅支援一部分的 Linux 檔案系統功能。

在上面能跑的東西其實已經不少了,而且除去一些還沒完成的部分以外,用起來真的幾乎跟直接裝一套 Ubuntu 沒兩樣,微軟發佈這份投影片時 top 還不能用,但實際上在 Build 14393 中已經沒問題了!

看完介紹了解這項功能的基本操作之後,請轉往下一頁閱讀安裝教學哦!

安裝教學

【警告 WARNING】
這項功能雖然會包含在 2016 年 08 月發布的 Windows 10 周年更新中,但仍然被標示為搶鮮版且預設不會啟用 (也就是其實開發工作還沒完成的意思),因此若無特殊需要,站長並不建議一般使用者啟用這項功能,這項功能可能導致電腦產生額外潛在不穩定因素甚至造成資料遺失或損毀的風險。

請注意,僅有 64 位元版本的 Windows 10 周年更新版本才具備此項功能,32 位元版本使用者無法使用。

Step 1. 進入設定 App 中的更新與安全性 → 開發人員專用頁面內,將模式切換為「開發人員模式」。

Step 2. 由於這項功能需要「適用於 Linux 的 Windows 子系統」作為基礎,因此請先到「控制台 → 程式集 → 開啟或關閉 Windows 功能」中將這項功能啟用。

Step 3. 由於這項功能牽涉到作業系統核心程序部分功能的啟用,因此會需要重新啟動電腦。

Step 4. 將作業系統核心內的 WSL 模組啟用之後,我們還得把 Ubuntu 子系統裝起來才能實際使用 (其實站長我頗好奇未來會不會有其他 Linux 發行版的子系統可用,我個人比較習慣 CentOS),接下來請手動執行「bash」這支程式 (打進搜尋裡就有了)。

Step 5. 再次提醒這項功能還沒有開發完畢,確定要安裝請用鍵盤輸入 “Y” 之後按下 Enter,系統會開始從 Windows 市集把這套由微軟與 Canonical 合作開發的簡化修改版 Ubuntu 14.04 LTS 下載回來。

Step 6. 安裝需要一點時間,完成之後會要求設定一組 Linux 子系統專用的帳號、密碼 (與 Windows 使用者名稱與密碼沒有關聯,這組純粹是 Linux 用的,在進行 Root 權限提升時會用到),在目前版本 (Build 14393) 中直接輸入 root 直接用 root 帳號登入也行,不過為了保險與安全起見請立刻用 passwd 指令改密碼

Step 7. 安裝完成囉,用起來感覺真的跟 Ubuntu 幾乎一模一樣。

使用範例

接下來我打算稍微 Demo 一下這個功能,由於我不想花太多時間想,所以就簡單以安裝 GNU C Compiler (GCC) 為例編一個 Hello World 看看吧。

Step 1. 首先用「apt-get install gcc」把編譯器裝起來。

Step 2. 用文字編輯器 (Ubuntu 內建的 nano 跟 vim 也都能用哦) 寫一個簡單的程式。

Step 3. 編譯並執行看看。

除此之外前面微軟投影片中曾經提到不能用的 top 在這個版本裡面也已經修復囉:

看到上面的記憶體使用資訊跟 Windows 工作管理員完全一致,使用的是完全相同的記憶體空間,這應該可以算是這東西相當接近原生執行的證明了吧?除此之外 Windows 工作管理員也能管理到 Linux 子系統正在執行的程序 (畫紅底線的部分,不過只能砍處理程序而已,並沒有實體路徑等資訊可以看)。

另一個使用範例則是安裝 Apache 作為 HTTP 伺服器使用 (由於是原生執行,所以網路環境也是完全共用的,因此 Apache 佔走 Port 80 之後,直接打開這台電腦的 localhost 出現的頁面就會是 Ubuntu 的預設 Apache 首頁了,不需要任何調整哦。

安裝指令:apt-get install apache2

疑難排解與移除、重設教學

如同電腦有可能會需要重灌一般,如果在使用 Ubuntu 子系統的時候發生問題或希望將整個子系統砍掉重練的話,微軟也有設計用於將 Ubuntu 子系統清除的機制。

移除並重設 Ubuntu 子系統的方式很簡單,使用「系統管理權限」執行命令提示字元,之後執行「lxrun /uninstall /full」指令即可,這個指令會將所有與 Ubuntu 子系統相關的檔案與設定徹底移除

接下來根據需求的不同有以下兩種情況:

最後如果你有需要重設帳號的問題的話 (應該是不會有忘記密碼的困擾啦,系統預設在打開 Bash on Ubuntu 的時候就會自動以儲存的預設帳戶登入了),可以試著執行「lxrun /setdefaultuser」指令來建立新的預設使用者。

效能測試

站長用於進行效能測試的機器是我手上的主力伺服器一號機 (ESXi 6.0),透過建立兩組設定完全一致的虛擬機器進行,至於測試項目則是 UnixBench。

Windows Subsystem for Linux

UnixBench 測試結果:247.3 pts (僅供參考,由於數據過於異常,站長打算近期再找時間補測。)

Native Ubuntu Server 14.04 LTS

UnixBench 測試結果:1286.4 pts

附表:目前 WSL 支援的 Linux SysCall 列表

不同 Windows 10 Redstone Wave 1 版本對 WSL 功能所能提供的 Linux 系統呼叫 (System Call) 有所不同,請參照下列的顏色了解在不同版本 Windows 10 內的 WSL 功能支援能力,若有重複出現情形者表示該 System Call 自該版本起又有強化或補充。

ACCEPT ACCEPT4 ACCESS ALARM ARCH_PRCTL
BIND BRK CAPGET CAPSET CLOCK_GETRES
CHMOD CHOWN CHDIR CLOCK_GETTIME CLOCK_NANOSLEEP
CLONE CLOSE CONNECT CREAT DUP
DUP2 DUP3 EPOLL_CTL EPOLL_CREATE EPOLL_CREATE1
EXECVE EVENTFD EVENTFD2 EPOLL_WAIT EXIT_GROUP
EXIT FACCESSAT FADVISE64 FCHDIR FCHMOD
FCHOWN FCHMODAT FCHOWNAT FCNTL64 FDATASYNC
FLOCK FORK FSETXATTR FSTAT64 FSTATAT64
FSYNC FSTATFS64 FTRUNCATE FTRUNCATE64 FUTEX
GETCPU GETCWD GETDENTS GETDENTS64 GETEGID
GETPGID GETEUID GETEUID16 GETPRIORITY GETGID16
GETUID16 GETPGRP GETEGID16 GETPEERNAME GET_THREAD_AREA
GETPPID GETRESUID GETRESGID GETRESGID16 GETRESUID16
GETGID GETRLIMIT GETRUSAGE GETSOCKOPT GETSOCKNAME
GETSID GETTID GETUID GETTIMEOFDAY INOTIFY_ADD_WATCH
GETXATTR KEYCTL GETPID GETGROUPS INOTIFY_INIT
LISTEN IOCTL LINKAT IOPRIO_SET GET_ROBUST_LIST
KILL LCHOWN LINK IOPRIO_GET PROCESS_VM_WRITEV
LLSEEK LSEEK LSTAT64 MADVISE MKDIR
MKDIRAT MKNOD MLOCK MMAP MMAP2
MOUNT MPROTECT MREMAP MSYNC MUNLOCK
MUNMAP NANOSLEEP NEWUNAME OPEN PROCESS_VM_WRITEV
PAUSE PIPE2 PIPE PERSONALITY PERF_EVENT_OPEN
POLL PPOLL PRCTL PREAD64 PROCESS_VM_READV
OPENAT PSELECT6 PTRACE PWRITE64 SCHED_GET_PRIORITY_MIN
READLINK READV REBOOT SETPRIORITY RT_SIGTIMEDWAIT
RECVMSG RENAME RMDIR RT_SIGACTION SCHED_SETSCHEDULER
RECV SELECT RECVFROM RT_SIGSUSPEND SCHED_GETAFFINITY
SEND SETGID SIGSUSPEND RT_SIGPENDING SCHED_SETAFFINITY
READ SIGACTION SETGROUPS RT_SIGRETURN SCHED_GET_PRIORITY_MAX
SETPGID SENDMSG SENDTO SCHED_YIELD SCHED_GETSCHEDULER
STAT64 SPLICE SETITIMER SENDMMSG RT_SIGPROCMASK
SETREGID SETRESGID SETRESUID SETTIMEOFDAY SET_TID_ADDRESS
SETSID SETREUID SETSOCKOPT SIGALTSTACK SET_THREAD_AREA
SYSINFO SETXATTR SIGPENDING SHUTDOWN SCHED_SETPARAM
SETUID SETRLIMIT SOCKETCALL SIGRETURN SCHED_GETPARAM
SOCKET SYNC SOCKETPAIR SETHOSTNAME SETDOMAINNAME
STATFS64 SYMLINK SYMLINKAT SIGPROCMASK SET_ROBUST_LIST
TEE TGKILL TIME UNLINKAT TIMERFD_GETTIME
VFORK TIMES TKILL TRUNCATE TRUNCATE64
UMASK UMOUNT UMOUNT2 UNLINK TIMERFD_CREATE
UNSHARE UTIME UTIMENSAT UTIMES TIMERFD_SETTIME
WAIT4 WAITPID WRITE WRITEV READLINKAT
SETGID GETEUID GETGID GETRESUID GETXATTR
PTRACE FCHOWNAT SETGROUPS SETHOSTNAME SETXATTR
EXECVE FALLOCATE LGETXATTR FGETXATTR GETTIMER
MKNODAT RENAMEAT SENDFILE SENDFILE64 SYNC_FILE_RANGE
LISTXATTR

 

Exit mobile version