4.3. Troubleshooting

接下來這節包括了一些有關 ports collection 常被問的問題和一些基本的 troubleshooting 技巧,還有假如 port 有毛病該怎麼做。

4.3.1. 一些問題和答覆

Q: 這是在討論 modem 吧?!
Q: 應該用 package 來安裝額外的程式嗎?
Q: 那為什麼用 port 來困擾人呢?
Q: 什麼是 patch?
Q: Tarball 是指什麼?
Q: 那 checksum 呢?
Q: 我照之前說的方法從光碟編譯 port 都很順, 怎麼一要安裝 kermit 就出槌?
Q: 我照做了,可是當要把檔案放進 /usr/ports/distfiles 卻得到沒有許可的錯誤訊息。
Q: Ports 的設計是只有把所有東西都放在 /usr/ports 下才能用嗎? 系統管理員說要把所有東西都放在 /u/people/guests/wurzburger 下,不過這樣好像不能用。
Q: 我並沒有 FreeBSD 的光碟,不過我想要有所有的 tarball 在手邊, 這樣就不用每次裝一個 port 就要等待下載。 有什麼好方法可以一次全抓下來嗎?
Q: 我知道從臨近的 FreeBSD mirror 站抓比較快。 可是有辦法從其它 MASTER_SITES 上面沒有的站抓 port 嗎?
Q: 要怎樣在 make 去抓檔案前先知道所需的檔案?
Q: 有辦法在 port 編譯前停止嗎?我想在它安裝前 hack 一下程式碼, 不過每次都要邊看邊按 control-C 很討厭。
Q: 我想試試做個自己的 port 並在有機會看看我的 patch 是否成功前停止編譯。有像 make extract 的指令不過是針對 patch 的嗎?
Q: 聽說有些編譯器的選項會造成錯誤。真的嗎? 怎麼確定用來編譯 port 的設定是正確的呢?
Q: 這麼多 port 害我很難找到我想要的。有可以取得的 port 的列表嗎?
Q: 怎麼原本要裝的 foo 裝到一半停下來跑去裝 bar?這是怎麼一回事?
Q: 我從 port 裡裝了 grizzle, 坦白說它很浪費空間。我想要把它砍掉可是不知道檔案放在哪裡。 有線索嗎?
Q: 等一下,這必須知道程式的版本才能用這個指令。 該不會真的希望我把它記下來吧?
Q: 說到了磁碟空間,ports 的目錄似乎佔去了嚇人的空間。 跑到目錄裡去刪除東西安全嗎?
Q: 我照做了,可是那個隨便你怎麼稱呼它的 tarball 還是在目錄 distfiles裡。 可以把那些也砍了嗎?
Q: 數以百計的程式我都想拿來玩看看。有辦法一次裝完全部的 port 嗎?
Q: 好吧,我試了,不過我以為會花很長的時間所以先跑去睡了, 讓它自己繼續下去。不過今天早上看電腦時,它只做好了三個半的 port。有哪裡出錯了嗎?
Q: 我實在很不想整天盯著螢幕看。有更好的主意嗎?
Q: 在工作上我們要用到 ports collection 裡的 frobble,不過我們已經修改了很多以符合所需。 有辦法做自己的 package 嗎? 這樣才能更容易的在我們的站上散佈這些 port。
Q: Port 好聰明。真想確定這怎麼做到的。秘訣在哪呢?

Q: 這是在討論 modem 吧?!

A: 啊,你一定是想到電腦背後的串列埠了。``port'' 在這是指把一個程式從一種版的 UNIX ``移植(porting)'' 到另一種版本的結果。

Q: 應該用 package 來安裝額外的程式嗎?

A: 沒錯,那是最快最容易的辦法。

Q: 那為什麼用 port 來困擾人呢?

A: 有幾個原因:

  1. 有些軟體發行的授權禁止以 binary 散佈。 它們必須以程式碼散佈。

  2. 有些人不信任 binary 的發行版本。 至少有程式碼可以自己瞧瞧有沒有潛藏的問題(理論上)。

  3. 如果有自己的 patch,要提供它們就必須有程式碼。

  4. 你可能和做好 package 的人在編譯程式方面有不同的意見 -- 有些人在最佳化的設定上有強烈的觀點, 不論是否是建立可除錯的版本再把它分開等等..

  5. 有些人喜歡有原始碼在身邊,這樣當無聊的時後可以拿來讀讀, 拿來 hack,借些點子(當然要版權許可!)和諸如此類的。

  6. If you ain't got the source, it ain't software! ;-)

Q: 什麼是 patch?

A: Patch 是一個宣告如何把檔案改成另一種版本的小檔案。 它包含純文字,而且基本上說明了類似 ``delete line 23'', ``add these two lines after line 468'' 或是 ``change line 197 to this'' 的事情。它們也以 diff 聞名因為它們是由 diff 這個程式產生。

Q: Tarball 是指什麼?

A: 它是一個以 .tar 結尾的檔案, 或是其它種類,諸如 .tar.gz .tar.Z.tar.bz2, 甚至是 .tgz

基本上它只是一個被包成檔案(.gz)的目錄, 或是選擇性的壓縮起來(.gz)。 這個技巧是來自於使用 Tape ARchives(所以叫做 tar), 不過被廣泛的應用於在網路上散佈程式。

可以自己看看裡面有什麼檔案,或是用陽春版 FreeBSD 系統 內附的標準 Unix 的 tar 程式把它解開來,就像這樣:

    % tar tvzf foobar.tar.gz
    % tar xzvf foobar.tar.gz
    % tar tvf foobar.tar
    % tar xvf foobar.tar

Q: 那 checksum 呢?

A: 這是一個由合計想檢查的檔案裡所有的資料所產生的數字。 如果有任何字元改變了,那 checksum 就不會再跟合計的結果一樣, 所以經由簡單的比較就可以偵察出差異。

Q: 我照之前說的方法從光碟編譯 port 都很順, 怎麼一要安裝 kermit 就出槌?

    # make install
    >> cku190.tar.gz doesn't seem to exist on this system.
    >> Attempting to fetch from ftp://kermit.columbia.edu/kermit/archives/.

為什麼找不到?難道這張光碟沒有用?

A: 就像在從光碟編譯 ports 那節所解釋的,有些 port 因為授權的限制不能放進光碟。Kermit 就是個例子。Kermit 的授權不允許把為它做的 tarball 放進光碟, 所以必須自己動手抓回來 -- 真是抱歉!

會有這些錯誤訊息是因為當時沒有連上網路。一旦從 MASTER_SITES (列在 Makefile 裡)中所列的任一個站把檔案抓下來, 就可以重新開始安裝的步驟了。

Q: 我照做了,可是當要把檔案放進 /usr/ports/distfiles 卻得到沒有許可的錯誤訊息。

A: Port 的機制是到 /usr/ports/distfiles 找 tarball,可是因為它是符號連結(symlink)到光碟的, 所以那個目錄唯讀而且也沒有辦法複製任何東西進去。 用下面說的方法就可以叫它去找其它地方:

    # make DISTDIR=/where/you/put/it install

Q: Ports 的設計是只有把所有東西都放在 /usr/ports 下才能用嗎? 系統管理員說要把所有東西都放在 /u/people/guests/wurzburger 下,不過這樣好像不能用。

A: 可以用 PORTSDIRPREFIX 這兩個變數來告訴 port 用別的目錄。 例如,

    # make PORTSDIR=/u/people/guests/wurzburger/ports install

會在 /u/people/guests/wurzburger/ports 裡編譯 port 並把所有東西安裝在 /usr/local 下。

    # make PREFIX=/u/people/guests/wurzburger/local install

會在 /usr/ports 裡編譯 port 並安裝至 /u/people/guests/wurzburger/local

毫無疑問的,

    # make PORTSDIR=.../ports PREFIX=.../local install

會結合這兩種(要在這頁完整的寫出來太長了, 不過它應該給你點概略了)。

如果不想每次安裝一個 port 就要把這些字再特別打一次, 把這設定放到環境變數裡會是個好主意。讀讀 shell 的 man page 來獲得做這些事的指引。

Q: 我並沒有 FreeBSD 的光碟,不過我想要有所有的 tarball 在手邊, 這樣就不用每次裝一個 port 就要等待下載。 有什麼好方法可以一次全抓下來嗎?

A: 要拿到 ports collection 每個 tarball 的話,執行:

    # cd /usr/ports
    # make fetch

要拿到 port 某個目錄下全部的 tarball 的話,執行:

    # cd /usr/ports/directory
    # make fetch

只要一個的話 -- 嗯,我想你應該早猜到了。

Q: 我知道從臨近的 FreeBSD mirror 站抓比較快。 可是有辦法從其它 MASTER_SITES 上面沒有的站抓 port 嗎?

A: 可以啊。如果知道的話,例如 ftp.FreeBSD.org MASTER_SITES 上面列的任何站都近, 那就這麼做:

    # cd /usr/ports/directory
    # make MASTER_SITE_OVERRIDE=ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/ fetch

Q: 要怎樣在 make 去抓檔案前先知道所需的檔案?

A: make fetch-list 會列出一個 port 所需的檔案。

Q: 有辦法在 port 編譯前停止嗎?我想在它安裝前 hack 一下程式碼, 不過每次都要邊看邊按 control-C 很討厭。

A:make extract 會在原始碼抓完並解開後停止。

Q: 我想試試做個自己的 port 並在有機會看看我的 patch 是否成功前停止編譯。有像 make extract 的指令不過是針對 patch 的嗎?

A: 有,make patch 就是了。 PATCH_DEBUG 這個選項也一樣好用。 順帶一提,多謝你的努力!

Q: 聽說有些編譯器的選項會造成錯誤。真的嗎? 怎麼確定用來編譯 port 的設定是正確的呢?

A: 是的,除非也有 -fno-strength-reduce 這個選項,否則 gcc 2.6.3 版(跟著 FreeBSD 2.1.0 和 2.1.5 一起出貨的版本)用 -O2 這個選項會造成有錯誤的程式碼。(大部份的 port 沒有用 -O2 這個選項)。 應該可以用下面的方法指定編譯器的選項

    # make CFLAGS='-O2 -fno-strength-reduce' install

或是藉由編輯 /etc/make.conf, 不幸地並不是所有的 port 都聽它的話。最穩當的方法是先執行 make configure,然後到原始碼的目錄手動檢視 Makefile,不過如果有很多子目錄, 而每個子目錄也有自己的 Makefile 做起來就很冗長乏味。

Q: 這麼多 port 害我很難找到我想要的。有可以取得的 port 的列表嗎?

A: 看一看 /usr/ports 裡的 INDEX 檔吧。如果要用關鍵字找的話, 也可以這麼做。例如要找和 LISP 這個程式語言有關的 port 就用:

    % cd /usr/ports
    % make search key=lisp

Q: 怎麼原本要裝的 foo 裝到一半停下來跑去裝 bar?這是怎麼一回事?

A: foo 這個 port 需要一些由 bar提供的東西 -- 舉個例子,假如 foo 會用到圖形,bar 可能有個函式庫包含很多有用的圖形處理程式。或者 bar 可能是編譯 foo 所需的工具。

Q: 我從 port 裡裝了 grizzle, 坦白說它很浪費空間。我想要把它砍掉可是不知道檔案放在哪裡。 有線索嗎?

A: 沒問題,只要這樣做:

    # pkg_delete grizzle-6.5

還有一個方法就是:

    # cd /usr/ports/somewhere/grizzle
    # make deinstall

Q: 等一下,這必須知道程式的版本才能用這個指令。 該不會真的希望我把它記下來吧?

A: 一點也不,照著下面做就可以找到:

    # pkg_info -a | grep grizzleInformation for grizzle-6.5:
    grizzle-6.5 - the combined piano tutorial, LOGO interpreter and shoot 'em up arc
    ade game.

Q: 說到了磁碟空間,ports 的目錄似乎佔去了嚇人的空間。 跑到目錄裡去刪除東西安全嗎?

A: 是的,如果程式已經裝好而且相當確定不會再用到原始檔, 那就沒有理由把它留在那裡閒晃。要這樣做最好的方法就是:

    # cd /usr/ports
    # make clean

這樣就會仔細檢查每個 port 的子目錄並且刪除 skeleton 以外的所有東西。

Q: 我照做了,可是那個隨便你怎麼稱呼它的 tarball 還是在目錄 distfiles裡。 可以把那些也砍了嗎?

A: 是的,如果確定它們已經沒利用價值,那就可以讓它們安心的走了。 可以手動移除或是用 make distclean

Q: 數以百計的程式我都想拿來玩看看。有辦法一次裝完全部的 port 嗎?

A: 只要執行:

    # cd /usr/ports
    # make install

Q: 好吧,我試了,不過我以為會花很長的時間所以先跑去睡了, 讓它自己繼續下去。不過今天早上看電腦時,它只做好了三個半的 port。有哪裡出錯了嗎?

A: 不是,是因為有的 port 需要問一些問題但我們不能幫忙回答 (例如``要印在 A4 或 US 信件大小的紙上?rdquo;) 而且需要有人在旁邊回答。

Q: 我實在很不想整天盯著螢幕看。有更好的主意嗎?

A: OK,在你 上床/工作/去公園 前做這件事:

    # cd /usr/ports
    # make -DBATCH install

這樣會把需要使用者做輸入的 port 都裝好。然後等回來後再執行:

    # cd /usr/ports
    # make -DIS_INTERACTIVE install

來完成這件事。

Q: 在工作上我們要用到 ports collection 裡的 frobble,不過我們已經修改了很多以符合所需。 有辦法做自己的 package 嗎? 這樣才能更容易的在我們的站上散佈這些 port。

A: 沒問題,假設已經知道如何對所做的改變做出 patch:

    # cd /usr/ports/somewhere/frobble
    # make extract
    # cd work/frobble-2.8
    [提供你的 patches]
    # cd ../..
    # make package

Q: Port 好聰明。真想確定這怎麼做到的。秘訣在哪呢?

A: 一點都不神秘,只要看看目錄 makefiles 裡 的 bsd.port.mk bsd.port.subdir.mk 這兩個檔。

(建議對 shell-scripts 有股莫名的厭惡的人不要看這個連結...)

4.3.2. 救命啊!這個 port 故障了(broken)!

如果遇到了自己不能用的 port,這有幾個可做的事,包括:

  1. 修正它!``如何做一個 port'' 這節應該會有所幫助。

  2. 訴苦吧 --只能用 email!首先寄 email 給 port 的 maintainer。鍵入 make maintainer 或是看 Makefile 來找 maintainter 的電子郵件地址。記得把 port 的名稱和版本也包括進去 (Makefile $FreeBSD: 那行)和出現錯誤前的輸出訊息一併寄給 maintainer)。如果沒有從 maintainer 得到回應,可以用 send-pr 的命令把 bug 回報。

  3. 忘了它。這是最簡單的途徑了 -- ports 裡的程式很少有被分類為``不可或缺的''。 當 port 更新到下一個版本時,任何問題都將很有可能會修好。

  4. 從臨近的 ftp 站抓 package。Package collection 的 ``主站''在 FreeBSD 的 FTP 伺服器 ftp.FreeBSD.org目錄 packages 下,不過請第一個看看當地的 mirror 站有沒有。這些 packages 比試著從原始碼編譯更有希望能執行, 而且更快!用 pkg_add(1) 這個程式來把 package 裝到系統上。