4.3. Troubleshooting

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

4.3.1. 一些問題和答覆

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

4.3.1.1. 這是在討論 modem 吧?!

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

4.3.1.2. 應該用 package 來安裝額外的程式嗎?

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

4.3.1.3. 那為什麼用 port 來困擾人呢?

有幾個原因:

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

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

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

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

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

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

4.3.1.4. 什麼是 patch?

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

4.3.1.5. Tarball 是指什麼?

它是一個以 .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

4.3.1.6. 那 checksum 呢?

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

4.3.1.7. 我照之前說的方法從光碟編譯 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/.

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

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

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

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

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

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

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

可以用 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 來獲得做這些事的指引。

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

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

    # cd /usr/ports
    # make fetch

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

    # cd /usr/ports/directory
    # make fetch

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

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

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

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

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

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

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

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

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

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

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

是的,除非也有 -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 做起來就很冗長乏味。

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

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

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

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

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

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

沒問題,只要這樣做:

    # pkg_delete grizzle-6.5

還有一個方法就是:

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

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

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

    # 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.

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

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

    # cd /usr/ports
    # make clean

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

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

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

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

只要執行:

    # cd /usr/ports
    # make install

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

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

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

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

    # cd /usr/ports
    # make -DBATCH install

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

    # cd /usr/ports
    # make -DIS_INTERACTIVE install

來完成這件事。

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

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

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

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

一點都不神秘,只要看看目錄 makefiles 裡 的 bsd.port.mkbsd.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 裝到系統上。