2008/06/27

我的心願

有一篇文章與大家分享,原文引自這裡,怕不見了就剪貼下來。在看文章之前,先說說我的心願,我是一直想跟朋友好好搞一下我的想法,建立一個虛擬世界。之前也不是沒有人想找我去負責當時流行的網路連線遊戲,只是我覺得那不是我真正想要的沒去。後來幾經週折,這幾年換工作快過什麼似的,目前,我只是想好好在現在的工作做個幾年,再累積一下人脈,若能工作與心願同時兼顧自然很好,若不能兼顧,就再晚個幾年吧。其實我的這心願存在不下十年了,我相信總有一天會實現的。這篇文章說的很好,希望將來我也能照亮別人。



玻璃業群聚 不斷寫奇蹟
‧Taiwan News 2008/06/26
「蠟燭不要一直拿在自己手上。一群人聚集在一起,把蠟燭逐一傳下,整群人都會被照亮,就算你手中沒有蠟燭,群聚就可以共享光明」。
【文/林明志】

中部濱海的中小企業 團結力量大

「蠟燭不要一直拿在自己手上。一群人聚集在一起,把蠟燭逐一傳下,整群人都會被照亮,就算你手中沒有蠟燭,群聚就可以共享光明」。林肇睢說,他大學時就喜歡登山,夜裡群聚在光亮處,夥伴共享共分攤,他說,群聚會產生巨大的力量,會在舞台發光發熱。

林肇睢是台灣首位實踐企業群聚的奇人,十年來,拿下世界最大家具品牌IEKA八○%的玻璃類產品,他說IEKA的十片玻璃,有八片是從他們手裡銷出去的。

十年前開始分享訂單

台明將十年前削價爭取到IEKA第一筆訂單一○○萬美金,同業分享訂單的原則進行玻璃群聚,十年後,IEKA的訂單多達四六○○萬美金,二○一三年,IEKA計畫將訂單量倍增到二億美金。

八十歲的IEKA創辦人坎普拉(Ingvar Kamprad)今年三月,特地從瑞典總部飛到台灣彰化,就是想一窺台灣玻璃產業的傳奇。

林肇睢是玻璃業界的奇人,中部業界喜歡稱呼他「大哥」。大哥不是混江湖;而是領導玻璃業界打拚,林肇睢為人四海,強調團結,他說,玻璃業是傳統企業,規模不大,想要生存就是團結打拚,就像打群架一樣,力量才能完全發揮,單打獨鬥容易遭到欺負。

從台明將公司說起,台明將前身為「信利行」,成立於民國三十二年,當時只不過是住家型的玻璃店,民國四十二年登記為「泉興鏡行」,七十三年正式成立「台明將企業」,現在的台明將資本額為一.五億,員工約一五○人,也是台灣玻璃龍頭台玻公司中部最大的經銷商。

台明將的成功之路

林肇睢說,從父親林將泉草創,他是二代接班,兒子林一翔退伍投入,家族三代在玻璃業界,從草創時期的四十坪廠房、二名員工,到今日漢寶本廠、一廠、彰濱工業區的玻璃館廠區,看盡玻璃產業的風華與慘淡及人間冷暖。

林肇睢輔仁大學體育系畢業,服完憲兵役退伍返鄉做玻璃,當時公司員工只有六人,專責從事玻璃販賣及簡易加工交易,由於人少事繁,父親每天都要清晨忙到晚,家族成員不眠不休的為公司打拚,林肇睢說,如果沒有突破,大家都會被累死、累病。

一定要突破規模與改變模式,是林肇睢始終存在的思維,他說︰「公司如果只能維持現狀,會累死老闆,損壞身體」「站在物競天擇,終有一天會被無情的淘汰」。林肇睢接管台明將之後,思考公司的長遠發展,與組織制度建立,他把「家族企業」轉化為「企業家族」,講究「傳賢不傳子」的經營理念。

「我不知道其他企業是怎麼經營?但我接管公司就是將經營權、所有權分離」簡單的說,就是員工與資方平均分享企業利潤,林肇睢的想法是,公司就是勞方與資方,不是誰較重要的問題,而是一樣份量,一樣共享共榮。台明將的員工分紅與資方一樣,不是資方取得絕對利潤後,再切割出員工享有的分紅,台明將的員工很喜歡此套模式,也很少人願意離開公司。

家族企業轉化為企業家族

家族企業轉化成企業家族,林肇睢說,玻璃業者要團結打拚,他把公司經營模式擴大到同業的結盟,協力廠商與台明將的份量是一樣的,他不是金字塔形的運作模式,台明將高高在上,而是環狀的配合模式,林肇睢解釋說,環狀的運作模式就沒有階級之分,產業策略是團結向國際競爭,這也是玻璃產業群聚的原始模型。

在台明將只有跟不上腳步的員工自動離職,林肇睢很少開除員工,在玻璃產業聚落裡,群聚的廠商對林肇睢信任,幾乎每位公司的管理階層,對林肇睢都豎起大拇指稱讚「大哥就是大哥」。林肇睢在大葉大學碩士進修,論文的專題就是他倡導的「產業群聚的效應」,目前他是彰師大機械所土博士班,專攻研究光學玻璃。

有人說,台明將不是玻璃業的大廠,資本額一億多,員工一百多人,卻有能力接下IEKA的千萬美金大單,IEKA的訂單每年都逐步增加,台明將到底怎麼辦到的?林肇睢說,表面上台明將不是大型企業,但是台明將背後的玻璃群聚業者,是最大的支柱,團結數十家,甚至上百家的中小型企業,不是可用資本額來計算的。

 林肇睢回憶,一九九八年,台明將以砍價二五%接下IEKA第一筆訂單,第二年與瑞典廠商比價,台明將再殺價三○%,二度爭取IEKA的訂單,瑞典的廠商原本擴充機器設備要與台明將比價,「瑞典廠商投資設備,就是為了接IEKA訂單,失去IEKA它什麼都沒有,只好宣佈倒閉!」林肇睢說,他就是帶領台灣玻璃業界打群架,IEKA的訂單就是我們的國際舞台。

隨時保持群聚優勢

IEKA訂單迷人卻有致命性,它的付款很乾脆,出貨二周內可以拿到貨款,但是採取全球開放競價,每年都會將產品的規格公開在網路上,歡迎全球供應商報價,能夠提供最好品質、準確交期與最低價格者,就有機會拿走訂單。IEKA的訂單策略,讓林肇睢戰戰兢兢,隨時保持群聚的優勢。

林肇睢說,每年競價取得的訂單,逐年增加,他所領軍的台灣玻璃群聚隨著增長,目前,台明將交付約三十家業者生產IEKA訂單,且代工IEKA的產值約佔每家代工廠的四成以上,林肇睢說,群聚最大的效應就是利潤共享,風險分攤,有錢大家做夥賺。

台明將是台玻公司的經銷商,同業需要的平板玻璃大都向台明將購買,因此台明將在業界的名聲很響,甚至南部業者都向台明將購買原料。林肇睢說,為了隨時支援玻璃同業生產所需,特別建構一個比台玻還要大的倉庫,庫存至少一萬二千噸,足以建造三棟台北一○一大樓,一○一大樓的玻璃外牆,約使用三千四百噸。

林肇睢說,他庫存大量的玻璃原料,是要做為群聚廠商的彈藥庫,也是設備的調度之一。他說,群聚廠商除了訂單的分享之外,包括設備、資金都是靈活支援調度,例如,群聚廠商需要生產設備,他會協助調度設備,折舊供給需要的廠商,另外,同業需要玻璃材料時,台明將會支援不預收現金,等到同業出貨收款之後再付錢給他。

協助業者站穩世界舞台

台明將的做法是不獨大,生產力彈性;同時降低風險,林肇睢說,訂單分享給同業,代表每個人都會賺錢,同樣代表風險分攤,不需要寡佔增加設備風險。有一次IEKA單品訂單原只有一百萬片,突然通知下個月要增到一千萬片,林肇睢說,一般業者根本無法接下單子,但是他們卻做到了,林肇睢通知群聚廠商增加產能,他們輕易通過考驗過關。

激增十倍的訂單,分攤給十多家業者,不需要太多壓力,但光靠單一廠商提供,根本無法交貨,況且新增生產線恐怕趕不上,如果訂單突然減少,閒置的設備成本,都會造成經營的困難。林肇睢的經營哲學,讓台灣玻璃中小企業站穩世界舞台,許多玻璃代工業者都想爭食IEKA大餅,但都無法順利取走訂單。

玻璃群聚走向彰濱工業區,為了加強運輸與材料支援,林肇睢首先響應進軍彰濱工業區設廠,他投資十二億買地蓋工廠,還到處遊說群聚廠商進駐,配合的廠商受到鼓舞,計有金潔明、福華、倩影等玻璃業者九家,廣義的玻璃相關業者包括鑄鋁、鐵管、玻璃與鏡子配套廠商等計有二十八家。

彰濱工業區原本未有玻璃加工專區,也因台明將領軍鼓舞業者進駐,工業區重新規劃設立「玻璃專區」。台灣玻璃業界的龍頭台玻公司,原本看淡台灣的玻璃產業到中國投資,十五年之後,台玻又在台灣投資二十億,重啟平板玻璃窯爐增產,且設置台玻鹿港彰濱廠,都是看中台明將倡導的玻璃群聚成果。

鼓勵業者留守台灣

林肇睢說,群聚越集中,發揮的力量與調度更靈活。台灣九○年代發生產業外移潮,台明將堅持不去中國,同時鼓勵業者留守台灣,以現今商場少見的義氣支持同業,讓群聚分享成長法則發揮到極致,十年來的努力,台明將的玻璃群聚打響國際知名度,誰也沒有想到,千萬美金龐大的產值,來自台灣中部濱海的中小企業,群聚的力量真可觀,它正在逐漸的壯大。

【更多精采內容請看《Taiwan News財經.文化週刊》第348期】

Bash 正規表示法的應用 -- 檢查 IP

本來譯自這裡, 原文的例子我個人覺得也沒什麼好的,就直接摘函式出來。

function valid_ip()
{
local ip=$1
local stat=1

if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}


實際在用的時候,可以像:
if valid_ip $ip; then 成功之後做點事; fi
不過若是簡單的 if, 我通常用這種寫法:
[ valid_ip $ip ] && 成功之後做點事;

上面提供的 valid_ip() 說真的很單純,也不完整,例如要判斷 192.168.1.* 就不行,不過就是提供大家參考怎麼用正規表示法也還不錯。這個範例裡提到 $? 是上一個命令的結果(True/False), local ip=$1 是引用呼叫函數傳進來的第一個參數。

2008/06/20

在 Bash 中使用 Array

本文大約翻譯自這裡,一般人若習慣傳統 xSH 的話,那可能不會想要使用陣列。

Bash 提供一個方便的陣列表示法,雖然在使用上不像 Perl, Python, PHP, 甚至 C/C++, Java, JavaScript 等那麼自然,但是當您會使用陣列時,一些困擾也自然解決。

先來看看表示法:
arr=(Hello World)

主要特點是用小括號,元素間用空白(不限個數)隔開即可。若要個別指定值的話,也很直覺如下:

arr[0]=Hello
arr[1]=World


與別的語言相對上較不直覺得地方在於引用時的語法,底下的範例中大括號是必要的,雖然這在 shell Script 中很常見,但是整個寫起來還是有那麼一點不順眼,習慣就好了:

echo ${arr[0]} ${arr[1]}


底下看一些比較特別的用法,摘要說明在後面註解裡:

$ arr=(hello world) # 初始化陣列,示範與空白數無關
$ arr[5]=. # 讓陣列不連續
$ echo ${arr[*]} # 引用陣列中所有元素
hello world .
$ echo ${!arr[*]} # 引用陣列的所有索引值,因為個別指定時有可能讓陣列跳過某些元素
0 1 5
$ echo ${#arr[*]} # 取得元素個數
3
$ echo ${#arr[0]} # 取得某元素的長度
5


底下用一個完整的範例來說明陣列用法:

#!/bin/bash

array=(one two three four [5]=five) # [5] 的用法較特別,請思考思考

echo "Array size: ${#array[*]}"

echo "Array items:"
for item in ${array[*]}
do
printf " %s\n" $item
done

echo "Array indexes:"
for index in ${!array[*]}
do
printf " %d\n" $index
done

echo "Array items and indexes:"
for index in ${!array[*]}
do
printf "%4d: %s\n" $index ${array[$index]}
done

$ ./test.sh
Array size: 5
Array items:
one
two
three
four
five
Array indexes:
0
1
2
3
5
Array items and indexes:
0: one
1: two
2: three
3: four
5: five


底下再用一個範例來示範未使用雙引號及使用雙引號搭配 *, @ 的影響:

#!/bin/bash

array=("first item" "second item" "third" "item")

echo "Number of items in original array: ${#array[*]}"
for ix in ${!array[*]}
do
printf " %s\n" "${array[$ix]}"
done
echo

arr=(${array[*]}) # 引用所有元素展開後,因為元素值有空白,因而造成新陣列變異
echo "After unquoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done
echo

arr=("${array[*]}") # 引用所有元素展開後,因為用雙引號括住,因而元素變成"一個"
echo "After * quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done
echo

arr=("${array[@]}") # 其影響請自行思考,非常重要
echo "After @ quoted expansion: ${#arr[*]}"
for ix in ${!arr[*]}
do
printf " %s\n" "${arr[$ix]}"
done

結果如下:
$ ./test2.sh
Number of items in original array: 4
first item
second item
third
item

After unquoted expansion: 6
first
item
second
item
third
item

After * quoted expansion: 1
first item second item third item

After @ quoted expansion: 4
first item
second item
third
item

2008/06/17

ooVoo? 視訊會議軟體

請參見 ooVoo

可以想成它跟 Skype, MSN 等軟體類似,用來做即時訊息傳遞,也包含 VIM 功能。底下翻譯一下其 features

.影像電話: 支援 HD 品質的影像電話
* 免費版一次可以跟三個人聊天(昇級後可以到六個人)
* 影像與聲音品質非常高且平順
* 沒人回話時(not on-line),可以留影像短片、聲音、或文字訊息
* 在視訊會議進行時,可同時傳送檔案或文字訊息(一如 Skype, MSN 等其它即時通)
* 可調整聲音或影像的輸出/輸入.
* 自訂電話鈴聲
* 可查詢對話歷程 (如未接來電,未通去電等).
* 視訊會議時可以調整影像特效

.錄影:昇級版方有此功能
* 可將影像電話(視訊會議)錄下來
* 錄影格式支援 AVI, FLV, 或 HTML embedded video.
* 最多可錄 1,000 分鍾的影像在 ooVoo 伺服器上,並且可以分享給別人,或在其他地方查詢

.影像訊息:
# 數量無限制的影像訊息,每則免費版上限一分鍾,昇級版五分鍾
# 可錄製並傳送給其他 ooVoo 好友,甚至包括未安裝 ooVoo 也行
# 一次傳送對象不受限制.
# 可在任何電腦播放影像訊息
# 可以儲存影像訊息在自己的電腦上
# 可將未錄製完成的影像訊息可以存在草稿區
# 創新你的生活。例如用影像訊息來製作邀請函,或廣告,或將你的旅行心得分享給其他人。

.影像特效:
* 例如更改大頭貼,加上帽子等等

.打電話:
* 可在北美地區,用來打電話,包括一般電話及手機

.文字模式即時通:
* 一次可與六個好友對話
* 容易邀請好友加入聊天室
* 可送訊息給離線好友

.傳送檔案:
* 傳送超大檔,最高到 25 MB
* 一次可傳送最多 20 個檔給多個好友
* 可傳送檔案給離線好友

.尋找好友:

.邊欄顯示:
* 將影像電話以邊欄顯示,儘量將桌面空出來

.公開您的 ooVoo 聯絡方式:
* 可放入任何 blog, 網頁,或是 email,甚至是簽名檔中
* 甚至可以指定「誰可以用 ooVoo 找我」

.隱私

如何把純文字檔放到 C 執行檔中?

請見 Embedding a File in an ExecutableConvert a File to a C Data Structure

一般方法至少三大類,最常見的就是利用 fopen 之類的 API 來自行處理 file I/O, 一種是第一篇文章說的,把 text file 轉成 object file 後再來引用指標的方式操作,一種是第二篇文章講的,將 text file 轉成 c char array struct。

先來看看文字檔,我改成多行:

$ cat data.txt
Hello, Wade.
This is a test line here
And this is the last line.
Add 4th line here.


底下是執行畫面,是在 cygwin 下執行的,因為 objcopy 的參數不太一樣,請修改成適當的,值得注意的是用 objdump 來看轉換後的 object file 內部的 symbol name 為 _binary_data_txt_start

$ objcopy.exe -I binary -O elf32-i386 -B i386 data.txt data.o

$ objdump.exe -x data.o

data.o: file format elf32-i386
data.o
architecture: i386, flags 0x00000010:
HAS_SYMS
start address 0x00000000

Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000054 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
00000000 l d .data 00000000 .data
00000000 g .data 00000000 _binary_data_txt_start
00000054 g .data 00000000 _binary_data_txt_end
00000054 g *ABS* 00000000 _binary_data_txt_size


底下列出測試用的 hello.c 及編譯、執行畫面,值得注意的是,因為 gcc 會在 extern symbol 前加上底線,因此命名方式跟原文不太一樣。


$ cat hello.c
#include

extern char binary_data_txt_start;
extern char binary_data_txt_end;

main()
{
char* p = &binary_data_txt_start;

while ( p != &binary_data_txt_end ) putchar(*p++);
}


$ gcc hello.c data.o

$ ./a
Hello, Wade.
This is a test line here
And this is the last line.
Add 4th line here.


第二種方式的 script 內容及執行畫面如下:

$ cat 2c.sh
#!/bin/bash

if [[ $# -ne 1 ]]; then
echo "Usage: $0 FILENAME"
exit 1
fi
file=$1

if [[ ! -f "$file" ]]; then
echo "File not found: $file"
exit 1
fi

cname=$file
cname=${cname//-/_}
cname=${cname//./_}

echo "static unsigned char $cname[] = {"
hexdump -v -e '" " 16/1 " 0x%02x, " "\n"' $file | \
sed -e '$s/0x ,//g'
echo "};"

$ ./2c.sh data.txt
static unsigned char data_txt[] = {
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x61, 0x64,
0x65, 0x2e, 0x0a, 0x54, 0x68, 0x69,
0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73,
0x74, 0x20, 0x6c, 0x69, 0x6e, 0x65,
0x20, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x41, 0x6e, 0x64, 0x20,
0x74, 0x68, 0x69, 0x73, 0x20, 0x69,
0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74,
0x20, 0x6c, 0x69, 0x6e, 0x65, 0x2e,
0x0a, 0x41, 0x64, 0x64, 0x20, 0x34, 0x74, 0x68, 0x20, 0x6c,
0x69, 0x6e, 0x65, 0x20, 0x68, 0x65,
0x72, 0x65, 0x2e, 0x0a,
};

2008/06/02

大括號的擴展 Bash Brace Expansion

本文大致是翻譯自bash 大括號的擴展

Bash 的大括號擴展非常有用,常見場合是命令列或 shell script 中用於產生序列字串。語法不難明白,底下用實例解釋。


{aa,bb,cc,dd} => aa bb cc dd
{0..12} => 0 1 2 3 4 5 6 7 8 9 10 11 12
{3..-2} => 3 2 1 0 -1 -2
{a..g} => a b c d e f g
{g..a} => g f e d c b a


大括號的擴展也可以在字串中:

a{0..3}b => a0b a1b a2b a3b

也可以是巢狀的:

{a,b{1..3},c} => a b1 b2 b3 c

為瞭解釋方便,底下舉一個用大括號擴展的片段:
for i in {0..19}
do
echo $i
done


其相當的 for 迴圈寫法為:
for (( i = 0; i <>


也可以用 while 來表達:
while [[ $i -lt 20 ]]
do
echo $i
let i++
done


再用一個 seq 改寫 for 迴圈的例子說明:
for i in $(seq 0 19)
do
echo $i
done


事實上,上面的例子都只能用在數字的情況,若是非數字的部份則無法採用同樣的方式,例如:
for i in {a..z}
do
echo $i
done

個人比較常用於長路徑時使用,例如:
cp /a/long/path/A /a/long/path/B TARGET
寫成
cp /a/long/path/{A,B} TARGET

通常可以少打很多字

在寫 shell script 中,有時反而希望 BASH 不要解釋這樣的大括號擴展,可以用 set +B來抑制,也就是預設是 set -B來啟用

搭配中括號的擴展也會對有效字串的產生非常有幫助,請自行搭配使用。