2010年9月21日 星期二

你不需要自由

Standard
曾幾何時,『自由』兩字變成了信仰,更變成了宗教狂熱,終以救世主姿態降臨。確實,我們都不喜歡被鎖在一片漆黑毫無自由可言的房中,許多心理實驗也證明了這樣做會造成人們發狂,但是自古到今,絕大多數人類被鎖在地球表面上卻也不曾為此發狂,尋思,自由有這麼重要嗎?我們又真的需要自由嗎?或許,我們只需要有能夠發洩的管道,其實自不自由一點都不重要。

歷史上為了自由而戰的事績何其多,有人為獨立而戰,有人為自己生存權利而戰,更有人為地位而戰,無論如何,大家追求的不過是長久心理壓力的出口。反觀當前科技業,近來開口自由軟體,閉口也自由軟體,暢導『自由』已不是為追求瓶頸出口,而是種貪婪的表現。到最後,雖不花分毫取得和掌控軟體各種權利,卻花了更大的代價去維護,甚至可能因無法控制而走火毀滅。

說到底,身為科技產業的商人要的是什麼?到底是軟體業合作廠商口袋裡的錢?還是市場上的錢?

一個通過重重升學考驗,有一技之長的精英,花了數十年成就一身,使用他們身上的東西,都有每個月個把萬的價值,更何況一個通過重重研發關卡的軟體,餵飽這些軟體的龐大成本更不在話下。而將這些軟體成本放在自己身上,更是種風險和壓力。所以,各自放出口袋不屬於自己的餅,丟掉這份不需要的自由,讓所有人共同追求最大利益不是更好?

一個商人或商業機構,追求利益的出口,無可後非,不過,一個皇帝可以穫得大片江山,卻不能任意奪取民脂民膏,更是不能忘記。

後記

若自由軟體不能勝任,就算熱愛自由軟體,也不應貿然使用,否則造成的後遺症,可不是打出『義和拳』推廣旗織就能解決的。

2010年9月8日 星期三

用 apt-get 節省系統開發和評估的時間

Standard
使用 Debian 系統(包括 Ubuntu)的人,應該早就熟於使用 apt-get 去安裝、移除或更新系統,其無痛和方便的操作,帶給 Debian 家族很大的優勢。而對於研發人員而言,我們比較在乎的是如何取得各套件的程式碼,更在乎的是能在『不出錯』的情況下將取得的程式碼完整編譯通過。

你可能碰到過一種情況,辛辛苦苦從各程式的專案首頁去抓回 Source Code 後,卻怎麼也無法在自己的電腦上編譯,單純點的情況是相依性問題,複雜點則是在不同系統上的相容問題,更誇張的是根本不清楚下載回來的 Source Code 是不是『真的沒問題』。相信很多人早已浪費過不少生命在這些麻煩問題上,導致開發效率低落,不過以上問題,卻在 Debian 裡相當容易解決,因為 apt-get 提供了一系列選項,讓我們輕易從下載原始碼、解決相依性問題、到確保通過編譯一次搞定。

# 下載套件原始程式碼:
apt-get source <package>
# 安裝該套件編譯過程必要的東西
apt-get build-dep <package>

從 apt-get 下載回來的程式碼,會在自動解開時將該 Package Maintainer 所做的 Patch 一併打進程式碼,以此方法解決系統相容性問題,這邊用 lxterminal package 為例,粗字部份就是在解壓縮時上的 patch:
$ apt-get source lxterminal
正在讀取套件清單... 完成
正在重建相依關係          
正在讀取狀態資料... 完成
NOTICE: 'lxterminal' packaging is maintained in the 'Git' version control system at:
git://git.debian.org/git/collab-maint/lxterminal.git
需要下載 293kB 的原始套件檔。
下載:1 http://ftp.tw.debian.org/debian/ sid/main lxterminal 0.1.8-2 (dsc) [1,372B]
下載:2 http://ftp.tw.debian.org/debian/ sid/main lxterminal 0.1.8-2 (tar) [280kB]
下載:3 http://ftp.tw.debian.org/debian/ sid/main lxterminal 0.1.8-2 (diff) [11.2kB]
取得 293kB 用了 1s (240kB/s)    
dpkg-source: info: extracting lxterminal in lxterminal-0.1.8
dpkg-source: info: unpacking lxterminal_0.1.8.orig.tar.gz
dpkg-source: info: unpacking lxterminal_0.1.8-2.debian.tar.bz2
dpkg-source: info: applying alt-number-key.patch
dpkg-source: info: applying hide-menu.patch
dpkg-source: info: applying fix_shortcuts.patch

再經過 apt-get build-dep 指令,會將 package 編譯需要的 library 或 Headers 安裝好,然後就可以接著用 ./configure 和 make 等步驟開始編譯了,如果沒有特殊意外(如:某些 package 需在 ./configure 的階段設定自有的參數),通常都會無痛編譯成功。

後記

通常在教育訓練或是和朋友談論研發議題時,總是推薦使用 Debian 系列的 Linux 發行版本(Debian 或 Ubuntu),通常原因就是其套件管理軟體能節省我們大量時間,而且其 Package 進入 Repository 的省核和驗證相當嚴格,並不容易得到壞的 source code package 。

2010年9月3日 星期五

超強大的 Bash - Networking 支援

Standard
當全世界都在瘋各種擴充性多元的 Script 語言時,所有人便開始遺忘 Unix 上古老的 Shell script,的確,和當今主流的 Python 、Perl 等語言相比,Bash 像個醜小鴨,但是不可否認,其功能和 footprint 的相對價值遠超過其他 script 語言甚多,因此在大多數 Linux 發行版之中,仍然會預設安裝 Bash 。

也因為 Bash 被太多人忽視了,很少人知道, Bash 其實也可以操作 Networking,舉例來說,可以一行指令便連上時間伺服器,透過 Daytime Protocol (RFC-867) 取得目前的標準時間:
$ cat </dev/tcp/time.nist.gov/13

55442 10-09-03 11:19:58 50 0 0 839.8 UTC(NIST) *

Bash 內建了這樣的功能,讓使用者可以透過讀寫 /dev/proto/host/port 的方式去操作網路連線,當然這路徑並不真實存在於系統中,所以透過其他的 script 或程式是無法存取。瞭解有這樣的功能後,我們也可以去試著去抓取網頁內容:
$ exec 3<> /dev/tcp/www.google.com/80
$ echo -e "GET / HTTP/1.1\r\nhost: http://www.google.com\r\nConnection: close\r\n\r\n" >&3
$ cat <& 3
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
Date: Fri, 03 Sep 2010 11:40:10 GMT
Server: sffe
Content-Length: 1354
X-XSS-Protection: 1; mode=block
Connection: close



<html><head>
... 內容省略
</body></html>

後記

使用 Shell script 是一種身為 Linux/BSD 等 Unix's like 系統工程師的基本技能,比起其他語言,其更為重要,況且現在的 Bash 已經有相當多的支援,足以讓我們做各種應用。

2010年9月2日 星期四

為你的程式加上 Debugging Mode

Standard
使用 C 語言開發程式,往往面對的都是數不盡的奇怪臭蟲,若想為程式除錯,通常會使用很多的 printf function,將所有程式執行的流程以及階段訊息印在畫面上。不過,太多的除錯訊息多半也會造成效能的影響,甚至是造成程式在使用上的不便。尋思,若能在 compile 階段設定是否開啟 Debugging Mode,對程式開發和最後包裝釋出,都可減少不少時間花費。

本文主要說明,如何利用 Autotool 和 C 語言 Macro,在 ./configure 執行階段決定啟動 Debugging Mode:
./configure --enable-debug

要達成目標,首先必需修改 configure.ac 並增加設定,使之後產生的 configure 檔案可支援 --enable-debug:
AC_ARG_ENABLE(debug,
              AC_HELP_STRING([--enable-debug], [Enable debugging]),
              CFLAGS="$CFLAGS -g -D_DEBUG")

然後在程式中的 C Header (確定該檔案是所有程式碼都會 Include 的 Header),加讓以下 Macro:
#ifdef _DEBUG
#define DEBUG(format, args...) printf("[%s:%d] "format, __FILE__, __LINE__, ##args)
#else
#define DEBUG(args...)
#endif

然後我們就可以在程式中使用 DEBUG() 的 Macro,用法和 printf function 一樣,只是該字串只在 Debugging Mode 被啟用時才會被編譯進程式裡:
void main()
{
    DEBUG("Debugging Mode was enabled\n")

    printf("Hello World!\n");
}

該程式執行後,就會看到類似下面的訊息:
[main.c:3] Debugging mode was enabled
Hello World!

由於在 C header 中設計的 DEBUG(),也包括了檔案名稱和程式碼行數,對於開發人員做除錯的工作就相當方便。