美思 [Windows] 程式設計教學:透過 Cygwin 使用類 Unix 系統上的軟體

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

Cygwin 是一套在 Windows 上運行的類 Unix 環境,除了 shell 環境外,Cygwin 提供許多類 Unix 系統上的終端機工具,以及附帶一個 X Window 環境。透過 Cygwin,類 Unix 系統使用者可以使用熟悉的命令列工具而不需重學另一套專門的工具。在 Bash on Windows 出現以前,大概都是用 Cygwin 來取得 Windows 上的類 Unix 子環境。在 Windows 8 (含) 以前的版本,沒有 Bash on Windows 可用,也是使用 Cygwin。

原本的 Cygwin 較不親和,需要進行較多的調校,而 Babun 提供了一套調校過的 Cygwin 環境,省下使用者自行調校環境的時間和心力。若讀者對 Babun 有興趣,可前往 Babun 的官網觀看相關資料。

安裝 (或重裝) Cygwin

本節展示安裝 Cygwin 的過程,仍然以正規的 Cygwin 來展示。不論是第一次安裝或新增套件,都要執行相同的安裝程式。

Cygwin 網站,下載安裝程式後,點擊以啟動該安裝程式:

啟動 Cygwin 安裝程式

Cygwin 的安裝程式有分 32 位元和 64 位元的,讀者可依自己的需求安裝。本文採用 64 位元安裝程式。

選擇安裝方式:

選擇 Cygwin 安裝來源

在本例中,我們是首次安裝,所以選擇從網路上下載套件。

選擇 Cygwin 安裝位置:

選擇 Cygwin 安裝位置

沒有特別的理由的話,按照預設的選項即可。

選擇本地套件位置:

選擇 Cygwin 本地套件位置

本地套件是為了節省下次下載所耗費的頻寬,所以位置最好固定在相同的地方。

因為我們先前選擇從網路下載套件,在這裡要選擇網路連線方式:

選擇 Cygwin 網路連線方式

按照系統上實際的情形來設置連線即可。

選擇下載套件的站台:

選擇 Cygwin 下載站台

理論上選站台時要選地理位置離自己的電腦近一點的,但筆者在測試時,台灣的站台反而無法順利下載套件,最後只得選個位於美國的站台。

安裝 Cygwin 的重頭戲是選擇套件:

選擇 Cygwin 套件

基本上是需要什麼就裝什麼,每個 Cygwin 使用者都有自己的需求,筆者在這裡就不給具體的建議。如果讀者不熟類 Unix 系統,也可以先用預設值,這時候就會只裝基本的套件。日後缺什麼套件再自行補上,比較能明確了解自己的需求。

Cygwin 安裝程式會進行最後的確認:

在安裝 Cygwin 前做最後確認

之後就跑安裝流程。實際安裝的時間會隨所選的套件多寡而定,通常在數分鐘內可完成。

最後安裝程式會詢問是否要新增捷徑:

新增 Cygwin 捷徑

這樣就跑完安裝流程了。如果讀者已經很熟類 Unix 系統,就可以開始使用 Cygwin 了。反之,如果讀者對類 Unix 系統不熟,可以參考這篇文章

Cygwin 的檔案結構

在 Cygwin 中,檔案結構參考 POSIX 環境,使用者會有家目錄 (home directory),軟體會裝到 /usr 等系統目錄中。在 Windows 中,整個 Cygwin 環境位於一個獨立的目錄中,像是 C:\Cygwin 等。不建議直接在 Windows 檔案總管中操作 Cygwin 中的目錄結構,最好還是用 Cygwin 的終端機環境操作 Cygwin 環境,以免造成不可預期的錯誤。

如果 Cygwin 使用者想和系統上的目錄及檔案互動,可以移動到以 /cygdrive 開頭的目錄,像是使用者 user 的使用者目錄在 Cygwin 中表示為 /cygdrive/c/Users/user 。透過這種方式,我們可以很方便地處理 Windows 上的目錄和檔案,像是使用 Cygwin 環境中的 wget 或 git 等工具下載檔案後,再用 Windows 上其他的軟體進行後續的處理。

在 Cygwin 中通常不需管理使用者和群組

由於 Cygwin 是 Windows 下的軟體,而不是一套作業系統,故沒有複雜的使用者和群組。基本上在 Cygwin 中,直接使用 Windows 系統的帳號,而該帳號即可同時做為一般使用者及管理者。點擊軟體即可進入 Cygwin 環境,也沒有額外的密碼。除了安裝軟體外,通常在 Cygwin 環境下都只做一般使用者的任務。

原本的 Cygwin 要安裝軟體時需離開 Cygwin 終端機,透過重新執行 Cygwin 安裝程式來安裝新的套件,而 Babun 可在不離開 Cygwin 環境下安裝新的套件。

在 Cygwin 中使用命令列工具

由於 Cygwin 是一個 POSIX 的 shell 環境,在使用像是 AWK 或是 Perl 等命令列工具撰寫 one liners 時,能夠在 POSIX 環境會比在 Windows 的 DOS 環境來得方便的多。另外,Cygwin 也支援 UTF-8 語系,對於文字串流,有一些幫助。還有一些像是 pipe 或 redirection 等 shell 的功能,方便使用者組合不同的命令列工具。例如,Emacs 在 Cygwin 下的使用效率也會比 Windows 的 DOS 環境佳。

然而,Windows 原生的軟體,無法辨識 POSIX 路徑,在 Cygwin 環境下呼叫 Windows 原生軟體時,需要以 cygpath 這套工具轉換路徑,轉換成 Windows 路徑後,再傳給 Windows 原生軟體。在下例中,呼叫 Windows 的記事本:

$ notepad "`cygpath -w /path/to/file`"

我們什麼時候會想在 Cygwin 下使用 Windows 原生軟體呢?像是 OpenJDK 會比 GNU 的 GCJ 支援度更好,我們就可以在 Cygwin 環境中編譯 Java 程式碼。

文字檔案的差異

雖然在 Cygwin 和 Windows 原生系統中,可以對同一個文字檔案用不同的工具來處理,但是這兩個系統對於文字檔案的處理上會有一些差異,主要在於 (1) 編碼 (encoding) 和 (2) 檔案結尾 (end of line),下文將分別敘述。

目前在類 Unix 系統主流的編碼是 UTF8,但 Windows 上的文字檔案多以系統的語系為主,如果文字檔案內只有英文的話,問題會比較小,但若文字檔案內有中日韓或其他國家文字,可能會造成亂碼出現。GNU/Linux 系統上可用 iconv 這套工具來轉換文字檔案的編碼;但 Windows 沒有此工具,可用安裝 Windows 版本的 Perl,利用其附帶的工具 piconv 來轉換文字編碼;piconv 的使用方式和 iconv 大抵上相同。

另外一個問題是檔案結尾,由於不同系統使用的檔案結尾不同,同一份文字檔案拿到不同系統時,可能會在斷行出現問題。有些編輯器 (editor) 可自動轉換,有些工具則無法自動轉換。如果需要手動轉換,可以用 dos2unix 這套小工具來進行轉換。

由於上述問題,筆者傾向不在 Cygwin 或 Bash on Windows 這類子系統中撰寫和編輯文字檔案,而會使用 Windows 原生環境的工具來處理文字檔案。

安裝 Cygwin 套件

在原本的 Cygwin 中,要安裝新的套件的話,要關掉 Cygwin 終端機,重新啟動 Cygwin 安裝程式,再挑選所需的工具。Babun 克服這個缺點,可直接在 Cygwin 環境中,用內部的套件管理軟體 pact 安裝所需的軟體。Babun 的套件管理程式稱為 pact

輸入 pact find 可搜尋可用的軟體:

$ pact find arj

輸入 pact install 可安裝軟體:

$ pact install arj

有關 pact 的其他使用方法,可見 pact --help 的說明。由於 Babun 算小眾軟體,pact 的教程偏少,要學著從 pact 本身的說明來學 pact 的用法。

選擇腳本語言

大部分自由軟體界的腳本語言,像是 Perl、Python、Ruby 等,都可以在 Cygwin 上使用。對於沒有用到 C 或 C++ 或 Fortran 的一般套件,應該都可以順利安裝;若要安裝延伸套件,則要安裝相對應的函式庫。較常見的函式庫都有相對應的 Cygwin 套件,少數 Cygwin 沒有提供套件的函式庫,就必需要自行編譯,編譯的方法和一般的類 Unix 系統差不多,Autotools (GNU Build System) 在 Cygwin 也可以通用。

標準 C 函式庫

Cygwin 並不是用 GNU 的 glibc,而是用 Red Hat 自己的 C 標準函式庫。原本這套函式庫是用於嵌入式系統,但 Red Hat 自行補足了不足的部分。大抵上和 GNU?linux 的 glibc 的 C API 差不多,偶爾會碰到一些細微的差異。

在 Cygwin 中編譯軟體的問題

要注意的是,在 Cygwin 上運行的工具透過特定 DLL (動態函式庫) 來模擬 POSIX,在編譯軟體時,也會連結到該 DLL,而和原生的 Windows 應用程式有所不同。

如果需要一些 GNU/Linux 下的軟體,而 Cygwin 沒有提供,也可以試著自行編譯軟體。雖然,比起原生的 GNU/Linux 環境,Cygwin 提供的函式庫的豐富度和完整性仍有一些些差距;對於相依性較單純的軟體,時常可以成功編譯;在編譯前,可查詢一下 Cygwin 是否已提供函式庫,以免浪費時間重覆編譯。

編譯成功後,執行檔即可在 Cygwin 環境中使用;然而,透過 Cygwin 環境編譯出來的軟體,不是原生的 Windows 應用程式,而依賴於 Cygwin 特有的函式庫。雖然我們也可以在 Cygwin 環境中交叉編譯出原生的 Windows 應用程式,通常會建議使用 MSYS 來編譯 Windows 原生應用程式,以免不慎混入 Cygwin 特有的的函式庫。

結語

對於在 Windows 中,又想使用 POSIX 環境下的工具,Cygwin 提供一個很好的方案。雖然不若原生的 Linux 環境來得完整,但對於一般性的任務已經足夠。Bash on Windows 出現後,和 Cygwin 有著微妙的競爭關係:雖然兩套軟體來自不同的開發團隊,操作的思維相當接近,讀者可自行選擇喜好的方案。

關於作者

身為資訊領域碩士,美思認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

美思喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,美思將所學寫成文章,放在這個網站上和大家分享。