2009年2月27日 星期五

[筆記]ssh蕩劍十式(2)

07. 第五式:Port Fowarding A. port forwarding:
ssh -L 4321:REMOTEHOST:1234 maxsolar@REMOTEHOST
-L表示本地端的意思。本地的port 4321到對方的port 1234建立一個加密連線。 B. reverse port forwarding:
ssh -R 4321:LOCALHOST:1234 maxsolar@REMOTEHOST
-R表示遠端的意思。遠端的port 4321到本地的port 1234建立一個加密連線。 C.tunneling and port forwarding:
ssh -L 4321:REMOTEHOST:1234 maxsolar@THIRDHOST
這個比較有趣,結合了tunnelling跟forwarding,本地端port 1234建立一個加密連線到第三方主機,第三方主機會把封包轉送到遠端的port 4321。請注意紅色跟綠色連線標示,從第三方主機開始,連線就沒有加密,但是可以作到封包轉送。中國的資訊封閉,很多軟體就是透過這樣的原理接觸到其他國家的新聞。 08. 第六式:公鑰認證 A. 製作一個公鑰認證:可以允許使用者登入時不用輸入密碼(或是僅輸入密語,passphrase),也可以減少密碼曝光的機率。首先我們「只使用」ssh2, 因為他用的技術可以避免劊客封包攔截(middle of the man)。假設我們產生一個rsa的key pair(注意:以普通使用者身份執行,因為是要產生自己的key pair):
ssh-keygen -t rsa
此時會產生一對公鑰跟私鑰,放置的位置不必更動,預設是~/.ssh/id_rsa(私鑰)以及~/.ssh/id_rsa.pub(公鑰)。之後會要求你輸入密語(passphrase),你可以選擇按enter保持密語空白,也可以輸入密語。 任何人於任何時刻都不應該把私鑰傳送出去,特別是透過samba,需確定除了自己以外的使用者毫無存取自己家目錄的可能。 B. 把作好的公鑰傳送到信任的遠端。「信任」是一個很主觀的問題,遠端主機效率不好、很愚蠢的系統管理員或是有很厲害又愛搞破壞的使用者都可以算是不能信任。但無論如何,你不需要把自己的公鑰傳送到你不知道該不該信任的主機,雖然他只是公鑰。
scp ~/.ssh/id_rsa.pub REMOTEHOST:~/.ssh/LOCALHOST_pubkey ssh REMOTEHOST 'cat ~/.ssh/LOCALHOST_pubkey >> ~/.ssh/authorized_keys'
~/.ssh/authorized_keys是遠端主機儲存你個人公鑰的地方,字不要打錯了! 這時候你再利用ssh 連線到遠端主機,你會發現不用打密碼了;如果你在產生rsa的key pair時選擇輸入密語,這時出現的提示就是輸入密語,而非密碼。 C.我不想要輸入密語,可以嗎? 假設產生key pair時你沒有輸入密語,這個小段你可以不用理會。假設你輸入了密語,你可以「暫時」不用輸入密語:在本地端機器以普通使用者執行
ssh-agent bash ssh-add ~/.ssh/id_rsa
此時會要求輸入密語。輸入你先前產生的那個密語並交給ssh-agent來幫你自動回答密語,此時你再使用ssh連線到遠端主機,就會連密語也不會問了!不過關閉這個shell,整個ssh-agent也會結束,要相同目的只能重作一次。 D.附記:遠端連線不用輸入密碼是很愉快的事情;事實上,在步驟B時,使用者也可以愚蠢的把本地端自己的私鑰傳到遠端主機;別懷疑,也是可以達成不用輸入密碼的效果!不過如果你的authorized_keys權限不是600的話,那可真的是令自己陷於水火之中呢! 09. 第七式:取得公鑰 當你連線到遠端主機,你會被提示是否要加入遠端主機的公鑰,因此取得公鑰是容易的事情。不過有時候系統管理員會因為安全性設定(ssh_config裡的StrictHostKeyChecking設定為yes),導致使用者無法增加新的公鑰,得到如下的錯誤訊息:
No RSA host key is known for planck and you have requested strict checking.
Host key verification failed.
使用者必須手動加入遠端主機的公鑰到~/.ssh/known_hosts裡:
ssh-keyscan -t rsa REMOTEHOST > REMOTE.pub cat REMOTE.pub >> ~/.ssh/known_hosts
假設管理員設定ssh_config將該遠端機器排除連線,那麼手動加入也沒有效果。 10. 第八式:基本的安全性設定 server端:/etc/ssh/sshd_config
AllowUsers                 #限定可以登入的使用者。
DenyUsers                  #同時存在時,以Deny為主;多個使用者以空白鍵分開
Protocol 2                 #ssh version 2
ListenAddress              #用address:port表示
Port 22                    #改變port number
PasswordAuthentication no  #設定成no。我們使用的不是密碼認證。
UsePAM yes                 #使用PAM認證
PermitRootLogin no         #不允許root登入
X11Forwarding yes          #允許遠端傳圖形至本機
client端:/etc/ssh/ssh_config
Host *                     #可限制遠連線主機
ForwardX11 yes             #允許遠端傳圖形至本機
Protocol 2                 #僅允許使用者使用ssh version 2
PasswordAuthentication no  #設定成no。我們使用的不是密碼認證。
StrictHostKeyChecking yes  #預設是ask。設定成yes可以限制使用者只連線已在
                           known_hosts裡的主機。
11. 第九式:以denyhosts保護你的ssh伺服器 請確保denyhosts會在開機時啟動:
insserv denyhosts
檢查看看有沒有在正確的runlevel啟動:
chkconfig -l | grep denyhosts
以下是列出/etc/denyhosts.conf比較重要的部份:
SECURE_LOG = /var/log/auth.log (Debian only)
HOSTS_DENY = /etc/hosts.deny
PURGE_DENY =                 #PURGE_DENY定義多久以後清除被封鎖的主機。
                             空值表示永不清除。
BLOCK_SERVICE  = ALL         #BLOCK_SERVICE定義被限制的daemon名稱。
DENY_THRESHOLD_INVALID = 1   #定義了無效的使用者名稱的登入次數。
DENY_THRESHOLD_VALID = 4     #除root外,有效的使用者名稱最高容忍登入錯誤次數。
DENY_THRESHOLD_ROOT = 1      #root所能允許錯誤登入次數。
                             其實這已無所謂,因為我的sshd並不允許root登入。
DENY_THRESHOLD_RESTRICTED = 1
SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES
    #如果設定為YES:如果從allowed-host中可疑的試圖登入結果,被認為是可疑的
    #如果設定為NO :如果從allowed-host中可疑的試圖登入結果,不會被報告記錄
    #(所有可疑登入的IP位址不在allowed-hosts中,皆會被報告紀錄)
HOSTNAME_LOOKUP=YES         #如果設定為YES:每個IP位址會被記錄在Denyhosts,
                          符合的主機名稱同樣的也會被查詢且紀錄
DAEMON_LOG = /var/log/denyhosts #log位置。
需要特別自訂的參數大致上是這些,你也可以參考
Bad IPs來寫進/etc/hosts.deny。 12. 第十式:掛載ssh filesystem 假設您已經安裝了sshfs,你可以這樣掛載sshfs:
sshfs maxsolar@REMOTEHOST: mountpoint
也許會出現:
failed to open /dev/fuse: Permission denied
解決的方法很簡單,把使用者加入fuse群組裡即可。卸載sshfs則是
fusermount -u mountpoint
您也可以參考:[筆記]ssh蕩劍十式(1) 參考來源: http://zh.wikipedia.org/wiki/OpenSSH http://www.openssh.org/manual.html http://linux.vbird.org/linux_server/0310telnetssh.php Netman老師寫的:ssh的一些技巧心得

[筆記]ssh蕩劍十式(1)

01.What is OpenSSH?
根據維基百科:「OpenSSHOpen Secure Shell)是使用SSH透過計算機網路加密通訊的實現。它是取代由SSH Communications Security所提供的商用版本的開放原始碼方案。目前OpenSSH是OpenBSD的子計畫。OpenSSH常常被誤認以為與OpenSSL有關聯,但實際上這兩個計畫的有不同的目的,不同的發展團隊,名稱相近只是因為兩者有同樣的軟體發展目標──提供開放原始碼的加密通訊軟體。」
也就是說,我們在linux平台上快快樂樂使用的ssh,其實是所謂的openssh,也就是ssh的開放原始碼版本。ssh以及其加密原理不是本文所關心的議題,在本文中只關心ssh的基本應用。
aptitude install ssh sshfs denyhosts
02.ssh蕩劍十式簡介:
A.遠端登入:ssh maxsolar@REMOTEHOST (搭配-X作X11Forwarding)
遠端執行:ssh maxsolar@REMOTEHOST 'command'
B.遠端複製:scp /local/path/foo maxsolar@REMOTEHOST:/remote/path/
C.遠端同步:rsync -ave ssh username@server1name:/home/ /export/home/
D.加密ftp傳輸:sftp maxsolar@REMOTEHOST
E.Port Forwarding: ssh -L 1234:REMOTEHOST:4321 maxsolar@REMOTEHOST
F.公鑰認證:ssh-keygen (包含ssh-agent + ssh-add)
G.取得公鑰:ssh-keyscan
H.基本安全設定:
I.防護你的ssh伺服器:denyhosts
J.掛載sshfs
03. 第一式:遠端登入及遠端執行命令 傳統的rlogin、telnet、rsh都是沒有加密的連線,我們不管在任何時刻都不應該在繼續使用他們;取而代之的連線方法是ssh。常用的參數為-X,可以讓遠端的圖形傳到自己的xserver來。 沒有使用ssh的年代,使用telnet遠端連線要實現傳送遠端圖形需要下列指令: localhost端:
xhost +REMOTEHOST; telnet REMOTEHOST
到remotehost端後:
export DISPLAY=LOCALHOST:0.
這個方法不僅麻煩,如果client端是撥接上網,沒有固定ip,或是透過nat上網,那麼設定DISPLAY時就是痛苦萬分,因為你無法告知遠端一個private ip去作X11Forwarding。
How to make sure we can have X forwarding? 請同時檢查client端與server端。查看本地端的/etc/ssh/ssh_config,是否有設ForwardX11 yes(或是#ForwardX11 no)。 server端請檢查/etc/ssh/sshd_config是否有X11Forwarding yes(或是#X11Forwarding no) 如果沒有,請修正之並重新啟動sshd;之後你就可以透過
ssh -X maxsolar@REMOTEHOST
遠端連線並傳回遠端圖形。 遠端執行 跟遠端登入是一樣的道理,只是有時為了執行一件小事情,不需要勞師動眾的連線過去為的只是去看一個小檔案。例如你只是要修改遠端的一份文字檔,你可以用一對單引號把command包住:
ssh -X REMOTEHOST 'gedit text.txt&'
同樣的,能不能出現圖形必須看ssh兩端的設定檔。 04. 第二式:遠端複製 利用scp作遠端複製,用法跟cp完全相同。
scp /local/path/foo maxsolar@REMOTEHOST:/remote/path/
把本地的foo檔複製到遠端的/remote/path下。
scp maxsolar@REMOTEHOST:/remote/path/foo /local/path/
把遠端的foo檔複製到/local/path底下。 我們可以從這個例子學習到兩件事情: A.username可以不加。假設遠端跟本地使用者名稱相同(uid可以不同),加不加username都不影響結果。假設你希望用遠端不同的username去執行,才要另外指定username。例如:
scp /local/path/foo maxubuntu@REMOTEHOST:/remote/path/
就是以遠端的maxubuntu身份來執行。 B.路徑的表示法可以是絕對路徑,也可以是相對路徑。例如:
scp linux_guide.odt REMOTE:docs/linux/
相同於
scp linux_guide.odt REMOTEHOST:/home/maxsolar/docs/linux/
05. 第三式:遠端同步 利用rsync搭配ssh可以使兩地主機資料同步且避免封包被解析出原始資料。
rsync -av -e 'ssh -l username' REMOTEHOST:/home/ /export/home/
將server1的/home備份到本機的/export/home來。
rsync -avz --delete -e 'ssh -l username' REMOTEHOST::/home/ /export/home/
兩個冒號是使用遠端的rsync server,若本地端loding很重時可以使用。 詳細的筆記請參閱:rsync簡易用法 06. 第四式:加密的ftp傳輸 透過sftp來代替傳統未加密的ftp協定。
sftp maxsolar@REMOTEHOST
所有的指令都有分成本機或遠端,例如ls是顯示遠端清單,lls顯示local清單。
get:抓取資料。搭配-P把metadata(權限、mtime、atime全部保留)一起轉移到本機。
put:上傳資料。
更多的資訊請man sftp。不過你應該可以使用filezilla來搭配sftp:
Fig 1.Filezilla的介面。 Fig 2.開啟站台管理員。伺服器類型選擇sftp,登入形式為一般。如果必要的話,字碼集的分頁可定為「強制使用UTF-8」。
Fig 3.第一次登入會要求加入公鑰。
從此後可以快快樂樂的使用sftp,把ftp忘記。不過他並不提供匿名的ftp服務,因此不適合對外當成file server。另外,假設某一端的網路環境較慢,sftp傳輸的速率也會比傳統未加密的ftp來得慢。 您可以再參考:[筆記]ssh蕩劍十式(2)

2009年2月25日 星期三

監看系統sockets狀態

發現一個很不錯的小程式可以快速的讓系統管理員監看系統的socket狀態:sockstat。 一般而言,系統管理原需要從netstat的資訊大海裡撈到想要的東西,在freebsd世界裡socket聽說已經行之有年了,有網友發現他已經被port到debian裡了!你可以直接安裝他!
aptitude install sockstat
分析一下他的用法:
-c:          顯示已連線的socket
-l:          顯示監聽中的socket。不加參數時,預設顯示-cl。
-h:          help
-p 8080:     指定port來顯示
-P 2340:     指定pid來顯示
-U maxsolar: 指定使用者
-G maxsolar: 指定群組
簡單好用,跟大家分享。

螢幕畫面錄影--xvidcap

之前在moto學園的討論串,有網友詢問在linux下有沒有類似anicam的工具可以用,實際上是有一兩個替代方案;不過本文討論的是xvidcap,一個簡單的螢幕畫面錄影工具。
dpkg -l xvidcap || aptitude install xvidcap -y
Fig 1.把xvidcap叫出來的畫面。那個歪歪的...是compiz特效啦^_^|||
Fig 2.錄影前可以先拉大所要錄影的範圍。當然範圍越大,所耗的資源跟影像也會越大 (聽起來像廢話@@)
Fig 3.xvidcap是支援暫停的。按下停止,就會儲存剛剛的紀錄。 你可以在家目錄下找到test-0000.mpeg這個錄影檔。
Fig 4.利用totem播放剛剛的動作,剛好紀錄下我正在作Fig 2的screenshot的畫面。

其實還有透過vnc來作螢幕錄影的工具,不過實在沒有時間去嘗試;如果你有相關的紀錄或經驗,請你不吝告訴筆者。

實際上xvidcap的運行是有些缺點在的:
1.xvidcap會不預期的當掉:筆者的經驗是好不容易辛辛苦苦想錄下螢幕的動作,但是xvidcap老早就當了,而且你也不知道到何時當掉的,每次辛苦的動作又要重來,令人生氣@@
2.xvidcap很吃資源:特別是你有開compiz的話,特別容易。筆者的電腦配備算是不錯(AMD Athlon 64 X2 Dual Core Processor 5000+,4G DDR3,nvidia 8800GTS顯示卡)要錄全螢幕(1680x1050)的畫面,總是不超過2分鐘必定當住。就算把特效關掉,我也不敢保證能夠安穩的錄多久@_@。我想畫面大小就看個人的配備而定了;至少當你需要的時候,是有那麼一個工具可以給你使用的!
3.無法紀錄聲音。

2009年2月24日 星期二

資源回收桶應用

在windows xp裡,刪除了一個檔案(當然是指圖形下),使用者可以很輕易的在資源回收桶裡找到該檔案並還原至原來的位置;however,我目前的gnome的環境已經到2.22,nautilus已經到2.20,竟然還是沒有實現原地回復的功能,必須要自己跑到垃圾桶下把檔案放到他應有的位置。在終端機環境裡,利用rm來刪除資料除了使用rm -i來多一層讓自己麻煩的問答外(特別是該目錄下有超過1000個檔案),一旦刪除了就沒有後悔的餘地;偏偏刪除的當下認為可以刪除,過幾天後才後悔為什麼不留著...


本文分別提供圖形與文字介面的資源回收桶介紹,有誤刪檔案情況的朋友可以參考。

1.圖形介面的檔案回復:

nautilus沒辦法從垃圾桶復原當原來的位置,因此我們不考慮用他;我們使用在XFce的好用檔案管理員:thunar來當我們桌面環境的預設管理。

dpkg -l thunar || aptitude install thunar
安裝完後,可以開啟他,試著刪除隨便一個檔案:
Fig 1.按右鍵可以選擇在桌面製作一個軟連結(捷徑),或是傳送到mail client,或是傳到floppy上。介面很接近pcmanfm,不過功能上是比較完整一點。

我們試著刪除這個檔案,再到垃圾桶裡去找他:

Fig 2.在垃圾桶裡找到這個檔案,可以不必為了到底他原本的位置在哪裡而傷腦筋;可以利用restore的功能,就會回復到原來的位置。

這是一個相當貼心的功能!thunar裡除了好用的檔案管理之外,你還可以使用他的重新命名檔案工具:Bulk Rename(批次重新命名),不過這不在本文的範圍,我關心的重新命名比較接近變更副檔名、變換大小寫。
如果你的需求跟我接近,或許您還可以參考:bash練習(1)--大小寫互換



2.文字介面下的檔案回復:

我們需要一個可以刪除該檔案,又能夠把刪除的檔案回覆到原地的好工具:safedelete。不過debian並沒有維護這個好東西,他是由redhat來維護的,不過別擔心,我們可以透過alien來把他轉換成deb來安裝:

wget -c ftp://ftp.muug.mb.ca/mirror/redhat/redhat/linux/7.1/en/powertools/i386/RedHat/RPMS/safedelete-1.3-10.i386.rpm && dpkg -l alien || aptitude install alien -y
alien safedelete-1.3-10.i386.rpm
dpkg -i safedelete*deb
接著,我參考Jamyy大大的部落格,裡面詳細的介紹基本的設定跟應用。如果你想知道safedelete所帶來的command有哪些,可以透過
dpkg -L safedelete | grep bin
可得知有四個command可用:safedelete, undelete,safecnvtsafedelchk
首先,在家目錄的.bashrc或是.profile多增加幾個變數跟別名:
export SAFEDAYS=30  #30天保存期限
alias rm='/usr/bin/safedelete'
alias rmreal='/bin/rm -i'
修改完別忘了讓shell重新讀取.bashrc或.profile。接著我們檢視一下safedelete的參數:
-i, --interactive
-v, --verbose
-f, --force
-r, -R, --recursive
看來跟原本的rm接收的參數都一樣,很好,那麼直接把rm換成safedelete是很安全的。
再檢視undelete的參數:
-i , --info, 也就是檢視檔案的詳細資訊,包含權限等等。
-l, --list, 列出清單
-f, --file
-r, --replace
-p, --pattern <pattern> 是很常用到的參數。
-a, --all,也是很常用到的參數。
那麼safedelchk的參數呢?
不加參數時,就是清除超過保期限的檔案。
-d 10: root only command。
   root要刪除所有超過10天的檔案。所得到的後果是,root的safedelete的SAFEDAYS
   變成10天,無論原先的設定是大於或小於10天。這個期限跟使用者設定的天數無關。
-u   : root only command。root使用safedelchk不帶參數時,會清除所有超過保存期限
   的檔案;root透過-u參數讓自己只清除被自己刪除的檔案,以避免清除到使用者的資料。
   不過man page裡提到一個有趣的現象:
   假設使用者使用"su"變成root,雖然身份是root,但是login shell還是使用者本人,
   此時使用safedelchk -u還是刪到自己的。
   正確的切換到root身份及root的shell應該要使用"su -"才對,請注意。 
safecnvt則是一個轉換log版本的指令,在此我們可以忘記他。

根據以上,我們作幾個小筆記:
rm ~/.happy
undelete ~/.happy #一個檔案簡單的回覆

rm -r ~/.books/  #刪除一整個資料夾
undelete -l      #先列出有哪些被我們自己刪過的檔案
undelete -p /home/$USER/.books/* -a
             #回復符合pattern的所有檔案。
             #就算指復原一個檔案,也會把該資料夾復原回來。

safedelchk       #清除超過保存天數的檔案。
需要注意的是,這個rm是safedelete的alias阿!如果想要用原本的rm硬幹的話,就用我們剛剛的別名吧:
rmreal -rf  .no_more_ms/ 

參考來源:Jamyy's Weblog
檔案來源:http://rpm.pbone.net/index.php3/stat/4/idpl/2402345/com/safedelete-1.3-10.i386.rpm.html

gromit螢幕畫筆

在windows的世界裡,有一套免費的螢幕畫筆軟體叫做ZoomIt,這是個很輕巧而好用的小工具,不但可以支援畫筆,還可以支援輸入文字,放大螢幕等功能。很可惜在linux下沒有功能並駕齊驅的好用工具,不過最接近的,應該屬gromit(GRaphics Over MIscellaneous Things)莫屬了。 在Debian下,可以直接安裝呢!
dpkg -l gromit || aptitude install gromit -y
安裝完後,可以開啟一個command接受視窗(利用Alt+F2),啟動gromit。此時的gromit在背景standby,想要使用畫筆快捷鍵整理如下:
pause key:    啟動/關閉gromit畫筆。(無法控制桌面)
ctrl+pause:   返回桌面控制狀態。(gromit畫筆還留在螢幕上)
shift+pause:  清除畫筆。(按一次清除後,需要再按pause一次才能真的清除畫筆,算是bug)
alt+pause:    離開gromit。(離開後gromit不在背景待命,若要使用畫筆需再次呼叫)
當你安裝好gromit之後,試著啟動她;預設會有下列功能:
左鍵:        紅筆
shift+左鍵:  藍筆
ctrl+左鍵:   黃筆
alt+左鍵:    粉紅色筆
中鍵:        使畫筆上色過的部份變成檸檬綠。
右鍵:        橡皮擦
shift+右鍵:  大橡皮擦
Fig 1.gromit畫筆。 很令人興奮,因為這足以具備利用螢幕來上課的功能了!
不過,你一定跟我一樣,認為想要其他的功能該怎麼辦呢?這時請先複製一份設定檔到自己的家目錄來:
cp /etc/gromit/gromitrc ~/.gromitrc
你可以複製我的.gromitrc來作修改,仔細推敲裡面的設定檔,您可以製作出更多的自訂功能!
# Configuration file for gromit
#edited by Jim T. Tang in 2009/02/24

# 定義Tools。
#定義畫筆,預設紅筆
"drawpen" = PEN (size=7 color="red");

#定義藍筆
"drawpen_blue" = "drawpen" (color="blue");
#定義藍色箭頭
"drawpen_blue_arrow" = "drawpen_blue" (arrowsize=1);

#定義黃筆
"drawpen_yel" = "drawpen" (color="yellow");
#定義黃色箭頭
"drawpen_yel_arrow" = "drawpen_yel" (arrowsize=1);

#定義粉紅色筆
"drawpen_pink" = "drawpen" (color="#ff00aa");
#定義粉紅色箭頭
"drawpen_pink_arrow" = "drawpen_pink" (arrowsize=1);

#定義綠色筆
"drawpen_green" = "drawpen" (color="green");
#定義綠色箭頭
"drawpen_green_arrow" = "drawpen_green" (arrowsize=1);

#定義檸檬綠筆
"drawpen_limegreen" = "drawpen" (color="Limegreen");
#定義檸檬綠筆箭頭
"drawpen_limegreen_arrow" = "drawpen_limegreen" (arrowsize=1);

#定義橡皮擦以及其大小
"eraser" = ERASER (size = 75);
#定義標注畫筆痕跡的顏色(檸檬綠)
"gruner Marker" = RECOLOR (color = "Limegreen");


# Mapping to Pointing devices(定義控制鍵)
#定義不使用任何按鍵時,使用預設畫筆(紅色)
"Core Pointer" = "drawpen";

#定義搭配shift鍵,為藍色畫筆。
"Core Pointer"[SHIFT] = "drawpen_blue";

#定義搭配ctrl鍵,為黃色畫筆。
"Core Pointer"[CONTROL] = "drawpen_yel";

#定義搭配alt鍵,為粉紅色畫筆。
"Core Pointer"[META] = "drawpen_pink";

#定義搭配shift+crtl鍵,為檸檬綠畫筆。
"Core Pointer"[SHIFT,CONTROL] = "drawpen_limegreen";

#定義搭配ctrl+alt鍵,為綠色畫筆。
"Core Pointer"[CONTROL,META] = "drawpen_green";

#定義搭配shift+alt鍵,為藍色箭頭。
"Core Pointer"[SHIFT,META] = "drawpen_blue_arrow";

#定義搭配shift+alt+ctrl鍵,為綠色箭頭。
"Core Pointer"[CONTROL,SHIFT,META] = "drawpen_limegreen_arrow";

#定義滑鼠中鍵,為標注顏色的檸檬綠畫筆。
"Core Pointer"[2] = "gruner Marker";

#定義滑鼠右鍵,為橡皮擦。
"Core Pointer"[3] = "eraser";

#定義shift+滑鼠右鍵為大橡皮擦。
"Core Pointer"[3 SHIFT] = "eraser" (size = 150);
這時gromit會讀取這個設定檔,而略過/etc/gromit/gromitrc。再啟動一次gromit來試試看吧:
Fig 2. 自訂出更多的畫筆功能!
很不錯吧,至少我們可以有一個很棒的螢幕畫筆小工具了!本文的最後,來個小小地結論來評論gromit的優缺點: 優點:gromit的自訂非常高,搭配的方式也很容易理解,自訂性筆ZoomIt高太多了。 缺點:跟ZoomIt比起來,她無法輸入文字,也無法放大螢幕,算是令人覺得可惜的地方。但是真正致命的的地方,是當gromit畫筆越來越多時,xserver的負擔會成指數般的變大;筆者在畫兩張快取圖時,後面的文字滑鼠已經寫過很久了,結果五秒鐘後才在螢幕顯現。因此使用gromit只好盡量避免太多筆劃產生,特別是你的機器有開Compiz特效時。 更多的功能,老話一句,man一下gromit就知道! 你可以參考Simon的網站,他的readme寫得很詳細,裡面也有更多的自訂方法以及他所知的bug。

2009年2月16日 星期一

成功大學校長致校友的一封信

親愛的學長及成大朋友: 元宵甫過,春蕊早開,大地一片欣欣向榮;祝您家庭美滿,事事順心。
自去年以來,世界經濟面臨極淒厲的寒冬,台灣是國際社會的一份子,免不了受到影響;許多公司行號或減薪,或放無薪假,甚或裁員,倒閉關廠,局勢之嚴峻,可以想見。根據本校學生申請就學貸款及各項助學措施的資料顯示,本校學生家庭受到經濟不景氣影響的數目有明顯增加之趨勢。而未來數個月,台灣產業界可能面臨更嚴酷的考驗。 我身為成功大學的校長,對於這樣的景氣,和大家一樣,也是憂心如焚。於是積極指示學校各單位,從不同面向協助學生,包括提供更多的獎助學金、工讀機會,以及急困濟助之資訊。我相信積極、適時的幫助學生,也就等於幫助了他們的家庭,幫助了社會。 在這一波金融海嘯中,有許多成大校友也難免受影響。為照顧這些校友,我們已擬定了因應策略,來幫助職場上被解僱而失業的校友,協助他們共度難關。這些策略包括提供就業資訊及再教育機會,配合教育部及國科會政策增加研究助理、博士後研究員及高階研究人員、增加產學合作計畫,並鼓勵智慧財產的開發、協助創業,此外,我們亦努力加速學校硬體設備的興建期程,以協助刺激經濟。 根據各國評估,這波不景氣的現象恐將維持一段時間;而四個月後,應屆畢業生又將投入職場,本校將約有一半的畢業生(成大最近每年畢業人次約五千人)選擇就業;在僧多粥少的環境下,勢必再出現另一波失業潮。為了未雨綢繆,亟需在企業界行有餘力的學長,提供就業機會或資訊,俾迅速傳達給學弟妹,好讓他們在溫暖的關懷中,跨出人生的第一步。 相信各位學長一定知道,成大畢業校友連續十年被選為企業界的最愛,這樣的成績,讓大家都與有榮焉!為維持得來不易的聲譽,迎接新血,注入源頭活水,當然是必要的。而如何集中力量,再創佳績,實需仰仗各位學長及成大朋友及時將機會與資訊提供給遭遇困難的校友與即將加入職場的社會新鮮人,讓學校扮演溝通的橋樑,為大家找到務實、積極、合群,以及有創意的生力軍。 成大校友的代代傳承及互相照顧,是成大最好的傳統。如果您的企業能幫忙,請您把這些資訊通知本校,可直接提供線上求才求職媒合網站「生涯達人資訊網」 (http://career.adm.ncku.edu.tw/),作為成大學長及朋友、校內大學部同學及碩博生們之就業機會或資訊共享平台,或提供訊息予成大校友聯絡中心(歐蓉蓉經理,電話:06-2757575分機81302,電子信箱:jjou@mail.ncku.edu.tw)。 我身為校長,幫助在校學生及畢業校友面對金融海嘯責無旁貸。校內方面,我們已經積極的動起來;校外方面,則懇請各位事業有成的學長及成大朋友們也和我們共同努力、彼此互助、共渡難關。 再度感謝各位學長及成大朋友的關懷與協助,相信以成大豐富的資源、成大人的熱心與團結,我們一定可以讓學弟、妹感受到來自前輩的提攜,進而以同理心回饋母校,奉獻家國。我還要衷心地呼籲:毋論需要幫助或可以幫助學弟妹的學長及成大朋友們,儘速與我們聯繫,讓我們同心協力,正面迎向逆境。並祝大家: 突破難關,宏圖大展! 校長 賴明詔敬啟
真希望我們校長的這封信,能讓在業界的主管級學長多照顧一下自己學弟妹!一起度過這個特別時期!我一直很喜歡我們成大的學長學弟制,那種互相提攜互相學習的感覺真的很棒,例如我在台南監獄的那段時間,也接受過學長的幫助,我也很努力的保護後面新進來的學弟免於受三區的志願役人渣的荼毒;這就像是一個不成文的規定,大家也都會去這麼做,這就是成大,這就是成大的傳統! 來偷學一下英文吧! An Open Letter from President Michael Ming-Chiao Lai to All Senior NCKU Alumni and Friends Dear Alumni and friends: The Lantern Festival has just passed and the spring flowers are blossoming. We are embraced by booming and prosperous sights and atmosphere! May you enjoy family bliss and all wishes come true! Since last year, the global economy has been in a dire situation. As a member of the international society, Taiwan is under the influence too: many companies and businesses either cut salaries, impose holidays without pay, lay off employees or go out of business. It is not hard to imagine how severe the recession is. Here at National Cheng Kung University, according to the data of our students’ application for study loans and various financial aids, there is an obvious increase in the number of students’ family affected by the recession. In the coming months, the industry in Taiwan might face even harder trials and tribulations. As the President of NCKU, I feel as anxious as everyone else about this situation; hence I have directed all university offices to provide various assistances for students, including more scholarships and financial aids, work study jobs, and emergency financial assistance. I believe that providing help to students actively and timely equals to helping their family and the society. Many NCKU alumni are swept by the economic tsunami. To support our alumni, we have planned coping strategies to aid those unemployed alumni to pass the hard times hand in hand. These strategies include: to provide employment information, upgrade training and education opportunities, increase slots for research assistants, post-doc and higher-level researchers in line with the policy from Ministry of Education and National Science Council, to add industry-academia collaboration projects, and to encourage intellectual property development and business start-ups. In addition, we also try to accelerate the construction schedules of facilities and building at NCKU to catalyze economy. According to predictions done by various countries, this recession might still continue for a period of time. Moreover, in four months, the coming graduates will enter the job market. About half of NCKU graduates will choose to start working (in recent years the average number of graduates are 5,000 annually). When the demand outnumbers the supply in the job market, there will come another high tide of unemployment. To prepare in advance, we need our successful senior alumni in the business world to provide employment opportunities and information to disseminate them to junior alumni, helping them to start a life in warmth and care. I suppose all alumni know that NCKU graduates have been regarded as the most desirable employees by the business world 10 years in a row, and all of us share this honor! To maintain this hard-earned reputation, it is essential that we embrace new blood and take in new vitality. To join our forces and reach a new pinnacle, we need your timely provision of employment opportunities and information to alumni in need and in-coming graduates. NCKU will act as the bridge for you to find pragmatic, enthusiastic, collaborating and innovative new crew! The pass-on and mutual help among alumni is the best NCKU tradition. If your business can help, please upload the information on the Employment Platform: http://career.adm.ncku.edu.tw/ . All members and associates of NCKU, from senior alumni, friends, undergraduate students, master’s and doctorate degree students can use this as a platform to exchange employment opportunities and information. Alternatively, please provide information to NCKU Alumni Association Center (Project Manager: Ms. Jong-Jong O, Tel: 06-2757575 ext 81302, e-mail: jjou@mail.ncku.edu.tw ) As the President, it is my duty to help all NCKU students and alumni to survive this financial tsunami. Within the university, we are in active mobilization to help our students, and outside the university we hope our successful senior alumni and friends will make an effort and work together to get out of this ordeal. I want to thank again for the care and assistance provided by senior NCKU alumni and friends. I believe that with the abundant resources, enthusiasm and united efforts, we will make our junior alumni see the support from their seniors, and in consequence they will pay back to the alter mater and our nation in the future. I also want to call sincerely for all NCKU alumni and friends, no matter you need help or can provide help, please contact us. Let’s join our hearts and hands together to meet the challenge head on. I wish all of us to conquer the tribulation and fulfill all ambitions! Michael Ming-Chiao Lai President National Cheng Kung University 以下則是校長給同學們的一封信:
親愛的同學們:
這幾週不斷有寒流來襲,讓人驚覺時序真的入冬了!而過完新曆年,學期即將結束,農曆年也接著到來。面對寒冬歲末,我謹在此先提醒大家保重身體!
當然,寒冬是四季遞轉的必然現象,但觀察今年的世界經濟,也面臨極淒厲的寒冬。台灣是國際社會的一份子,免不了受影響,許多公司行號或減薪,或 放無薪假,甚或裁員,倒閉關廠,局勢之嚴峻,可以想見。根據本校學生申請就學貸款及各項助學措施的資料顯示,本校學生的家庭受到經濟不景氣影響的數目有明 顯增加之趨勢。
我身為知識份子,身為成功大學的校長,對於這樣的景氣,和大家一樣,也是憂心如焚;尤其關心在成大就讀的你以及你的家庭。如果你能獨立應付,成 大願為你持續加油;如果你因為家庭的因素或其他原因而面臨困境,成大願助你度過難關!因為學校有許多獎學金(包含優秀獎學金、清寒獎助學金)、工讀及助理 工作,提供給同學申請,可以幫你自立更生!如果需要幫助的同學太多,學校將會增加這些獎助金的經費,和大家共度難關。
此外,如果你的困境是意外產生,措手不及,只要上本校網站首頁>在校學生>財務資訊>榕園圓夢助學網,或與導師及其他師長商討,就可以幫忙解決 問題。我們不願意看到任何一位同學因家庭經濟困難而不能留在成大就學。當然,有些同學比較忠厚保守,會覺得向人開口求助是丟臉的事。但每個人應該正面地迎 向困難,才是正確的態度!在這緊要的關頭,成大可以提供你穩住陣腳,繼續加油的動力,因為你是我們大家庭的一份子啊!除此之外,有些同學面臨畢業找不到工 作,有些在職場工作的校友被解雇失業,學校也正在思考規劃一些計畫,來幫助這些同學、校友,這些辦法不久就會公布。
西諺說:「樂觀的人,發明飛機;悲觀的人,發明降落傘。」是的!今天成大在國內所以能成為邁向頂尖的學府,成為企業界的最愛,正是因為有優秀的 同學,一代又一代的加入,才能讓我們昂揚前進。所以學校會照顧每位同學,而你進入成大,也就宣示了你有為學校及社會貢獻的能力與責任。豈可悲觀?
相信大家都非常敬仰、懷念前不久才辭世的台灣經營之神—王永慶先生,他成功的原因很多,但最關鍵的第一步,就是赴日本學習之前,向人開口求助, 張羅盤纏。等到事業稍有成就,不但還了借來的錢,還帶著感恩的心一輩子照顧那位他生命中的貴人;富甲一方後,甚至由照顧一人進而照顧千萬人,由回饋台灣進 而奉獻國際,真正印證了台語所謂的「食果仔拜樹頭」這句話。所以,開口向人求助,絕不會傷害你的尊嚴,反倒是考驗你是否有持志堅忍、懂得自我調適的能力。 處於現在經濟不景氣的時候,同學們最重要的是在學校打好基礎,不僅是專業的知識技術,更重要的是培養好的職業道德、個人品德、跨領域的知識、自我進修的能 力以及國際觀。把現在的危機變為契機,這才會讓你的未來無往不利。
我認為唯有懂得珍惜自己、尋求協助的人,才能自助助人。因此,我再度呼籲同學們,面臨全球金融大風暴,我們一定要有耐心、信心,以及「逆轉勝」的決心。同時更要充實自己,培養競爭力。相信:冬天到了,春天也不遠了!最後祝同學們:
學業進步
闔府平安!
成功大學校長 賴明詔

Forecast 附加元件-選擇位置

Forecast是在firefox上很有名的天氣預報的附加元件。我安裝的附加元件是Forecastbar Enhanced,不過有時會有找不到某都市的locale代碼。這時候可以參考 http://weather.yahoo.com/Taiwan/TWXX/regional.html 所提供的資訊,列出了我們台灣大部分的都市代碼。
Chi-lung      -基隆 -TWXX0003
Tan-shui      -淡水 -TWXX0024
Taipei        -台北 -TWXX0021
T'aipeihsien  -台北縣 -TWXX0022
Hsin-tien     -新店 -TWXX0010
Su-ao         -蘇澳 -TWXX0016
T'ao-yuan     -桃園 -TWXX0025
Hsin-chu      -新竹 -TWXX0009
Miao-li       -苗栗 -TWXX0014
Feng-yuan     -豐原 -TWXX0007
T'ai-chung    -台中 -TWXX0019
Chang-hua     -彰化 -TWXX0001
Chia-i        -嘉義 -TWXX0002
T'ai-nan      -台南 -TWXX0020
Kangshan      -岡山 -TWXX0012
Kao-hsiung    -高雄 -TWXX0013
P'ing-tung    -屏東 -TWXX0015
Hengch'un     -恆春 -TWXX0008
Hengchun      -恆春 -TWXX0027
Hua-lien      -花蓮 -TWXX0011
T'aitung      -台東 -TWXX0023
Taidong       -台東 -TWXX0028
Ta-wu         -大武 -TWXX0026
如果有更詳細的locale code,也請通知我一聲,謝謝!

2009年2月12日 星期四

Java小練習(16)--關於字串

題目要求: 撰寫一個名為Dog的class,並使其含有兩個公開的String : name以及says。在main()中分產生兩個Dog的物件,並將其命名為"spot",says值為"Ruff!"、以及"scruff",says值為"Wuff!"。印出他們的name以及says。 接著產生Dog的reference並且將他指派到表示spot的物件,分別使用"=="以及".equels()"來比降所有的reference。 ------------- code starts ------------------
public class Dog {

   public String name;
   public String says;

   public static void main(String[] args) {
       Dog d1 = new Dog();
       d1.name = "spot";
       d1.says = "Ruff!";

       Dog d2 = new Dog();
       d2.name = "scruffy";
       d2.says = "Wurf!";

       System.out.println("第1隻狗叫" + d1.name + ";而且他說:" + d1.says);
       System.out.println("第2隻狗叫" + d2.name + ";而且他說:" + d2.says);
       System.out.println("----------");

       System.out.println("把第2隻狗的名字指定給第1隻狗");
       d1.name = d2.name;
       System.out.println("第1隻狗叫" +d1.name);
       System.out.println("第2隻狗叫" +d2.name);
       System.out.println("兩隻狗物件的位置是否相同:" +(d1 == d2));
       System.out.println("兩隻狗名字的位置是否相同:"+(d1.name == d2.name));
       System.out.println("兩隻狗名字的內容是否相同:"+(d1.name).equals(d2.name));
       System.out.println("兩隻狗說話的內容是否相同:"+(d1.says).equals(d2.says));
       System.out.println("--------------------------");

       System.out.println("把第2隻狗整個物件指定給第1隻狗");
       d1 = d2;
       System.out.println("第1隻狗叫" +d1.name);
       System.out.println("第2隻狗叫" +d2.name);
       System.out.println("兩隻狗物件的位置是否相同:" +(d1 == d2));
       System.out.println("兩隻狗名字的位置是否相同:"+(d1.name == d2.name));
       System.out.println("兩隻狗名字的內容是否相同:"+(d1.name).equals(d2.name));
       System.out.println("兩隻狗說話的內容是否相同:"+(d1.says).equals(d2.says));

   }
}
------------- code ends ------------------ 雖然java傳值的方式是pass-by-value,對於基本型別來說容易理解,對於類別型別來說感覺上卻是pass-by-references。 不過我們可以這樣理解:java物件的pass-by-value是指記憶體的參考位置的值,所以傳遞的是reference的位置的值。很多程式設計師都說java的pass-by-value是強詞奪理,不過我們就聽聽吧!

2009年2月10日 星期二

Java小練習(15)--break與continue練習

break與continue搭配label來控制迴圈是很有趣的方法,我經常用他來判斷自己的想法正不正確。 我作一個巢狀迴圈,外迴圈跑6次,內迴圈跑4次,加入continue跟break來看看會發生甚麼有趣的事情。 --------- example 1 -----------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");             continue L1;
          L2:
          for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");              }             System.out.println();         }     } }
--------- example 1 ends ----------- continue放在第一層for迴圈的結果,會導致L2完全沒機會被執行到,執行結果是:
i=1        i=2        i=3        i=4        i=5        i=6
--------- example 2 ---------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");             break L1;
          L2:
          for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");              }             System.out.println();         }     } }
--------- example 2 ends --------- break放在第一層for迴圈的結果,會導致L2完全沒機會被執行到,執行結果是:
i=1
然而我們無法在這個地方放置break L2或continue L2,她會顯示找不到L2個標籤。 --------- example 3 ---------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");              L2:             for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");                 continue L2;
          }
          System.out.println();
      }
  }
}
--------- example 3 ends ---------
i=1        j=1        j=2        j=3        j=4     
i=2        j=1        j=2        j=3        j=4     
i=3        j=1        j=2        j=3        j=4     
i=4        j=1        j=2        j=3        j=4     
i=5        j=1        j=2        j=3        j=4     
i=6        j=1        j=2        j=3        j=4  
跑出來的結果可想而知,會跟沒有continue是一樣的,因為她本來就會重複作。 那麼如果是continue L1會如何呢? --------- example 4 ----------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");              L2:             for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.println("\t"); //換行以方便顯示
              continue L1;
          }
          System.out.println();
      }
  }
}
--------- example 4 ends ---------
i=1        j=1     
i=2        j=1     
i=3        j=1     
i=4        j=1     
i=5        j=1     
i=6        j=1
內迴圈作一次之後沒機會作第二次就跑到外迴圈了,所以苦命的內迴圈用永都只能作第一次。 --------- example 5 ---------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");              L2:             for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");                 break L2;
          }
          System.out.println();
      }
  }
}
--------- example 5 ends --------- break會脫離所標示的迴圈:即內迴圈,因此內迴圈永遠只能作一次。example 4跟5是一樣的結局。
i=1        j=1     
i=2        j=1     
i=3        j=1     
i=4        j=1     
i=5        j=1     
i=6        j=1
--------- example 6 ---------
public class LoopTest {

  public static void main(String[] args) {
      byte i, j;

      L1:
      for (i = 1; i <= 6; i++) {             System.out.print("i=" + i);             System.out.print("\t");              L2:             for (j = 1; j <= 4; j++) {                 System.out.print("j=" + j);                 System.out.print("\t");                 break L1;
          }
          System.out.println();
      }
  }
}
--------- example 6 ends --------- break會跳離標籤所示的迴圈:即外迴圈,因此只做一次就結束了。
i=1        j=1
很好玩吧!

Java小練習(14)--二維陣列

從練習13,我們作一個轉換:請印出下列表格:
28916981251
324196100364
361225121499
4002561446416
可以發現這是練習13順時針旋轉90度。但是我們從1~400給值必須從 [0][4]->[1][4]->[2][4]->[3][4]->換列 [0][3]->[1][3]->[2][3]->[3][3]->換列 [0][2]->[1][2]->[2][2]->[3][2]->換列 [0][1]->[1][1]->[2][1]->[3][1]->換列 [0][0]->[1][0]->[2][0]->[3][0]-> end 值給定之後,就可以依序列印。 ------------ code starts --------------------------
public class ArrayAssign2 {

    public static void main(String[] args) {
        int[][] bb = new int[4][5]; //建立一個4x5陣列

        int num = 1;
        for (int col = bb[0].length - 1; col >= 0; col--) {
            for (int row = 0; row < bb.length; row++) {
                bb[row][col] = (int) Math.pow(num, 2);
                num++;
            }
        }
        for (int row = 0; row < bb.length; row++) {
            for (int col = 0; col < bb[0].length; col++) {
                System.out.print(bb[row][col]);
                System.out.print("\t");
            }
            System.out.println();
        }

    }
}
------------------- code ends ---------------------------------------

Java小練習(13)--二維陣列

利用迴圈印出如下的排列:
12916
25364964
81100121144
169196225256
289324361400
由上表可以觀察出每個數字分別是由陣列[0][0]到[4][3]依序填入1~20的平方。只要我們能依序填入1~20,就有辦法填入他們的平方。 -------------- code starts -----------------------
public class ArrayAssign1 {

    public static void main(String[] args) {
        int[][] aa = new int[5][4]; //建立一個5x4陣列

        int num = 1;
        for (int r = 0; r < aa.length; r++) {
            for (int c = 0; c < aa[0].length; c++) {
                //利用兩個for迴圈把值一個一個塞進去
                //再利用Math.pow()來作平方計算
                aa[r][c] = (int)Math.pow(num, 2);
                System.out.print(aa[r][c]);
                System.out.print("\t");
                num++;
            }
            System.out.println();
        }
    }
}
------------------ code ends --------------------------

2009年2月9日 星期一

Java小練習(12)--二維陣列

根據Java小練習(11),我們用兩個一維陣列來完成。如果我們把程式碼改寫成一個二維陣列,寫法會比較靈活!
public class ArrayTest3 {

    public static void main(String[] args) {
        //data[月份][銷售業績],12x2的陣列
        int[][] data = { {1, 16}, {2, 15}, {3, 13}, {4, 11}, {5, 10}, {6, 10},
                                {7, 8}, {8, 7}, {9, 4}, {10, 3}, {11, 1}, {12, 0} };

        System.out.println("Microsoft vista九十七年度銷售業績");
        System.out.println("月份\t業績");
        System.out.println("---------------------------------");

        for (int m = 0; m < data.length; m++) {//列印月份
            System.out.print("data[m][0]");
            System.out.print("\t");
            for (int star =1; star<=data[m][1]; star++){//列印業績的*號
                System.out.print("*");
            }
            System.out.println(); //*號印完換列
        }
        //for 迴圈結束,列印總數
        System.out.println("----------------------------------");
        int sum = 0;
        for (int i=0; i< data.length; i++){
            sum += data[i][1];
        }
        System.out.println("the total is:" +sum+"萬元");
    }
}

Java小練習(11)

題目要求:印出如下表格:
Microsoft vista九十七年度銷售業績
    月份     業績
    ------  ------------------------------------------
    1
    2         ********
    3         *******
    4         *************
    5         *********
    6         ************
    7         **********
    8         ********
    9         **************
    10        *************
    11        **************
    12        ***************
   ----------------------------------------------------
    銷售金額:??百萬元
-------- code starts ---------
public class ArrayTest2 {

    public static void main(String[] args) {
        //month ->代表月份
        int[] month = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
        //data     ->代表銷售業績金額
        int[] data = {16, 15, 13, 11, 10, 10, 8, 7, 4, 3, 1, 0};

        System.out.println("Microsoft vista九十七年度銷售業績");
        System.out.println("月份\t業績");
        System.out.println("---------------------------------");
        //印出月份與業績
        for (int i = 0; i < month.length; i++) {
            System.out.print(month[i]);
            System.out.print("\t");
            //以下為列出*的迴圈,印初次數為data[i]
            for (int j = 1; j <= data[i]; j++) {
                System.out.print("*");
            }
            System.out.println();
        }

        System.out.println("----------------------------------");
        int sum = 0;
        for (int k = 0; k < data.length; k++) {
            sum = data[k] + sum;
        }
        System.out.println("總金額:" + sum + "百萬元");
    }
}

2009年2月8日 星期日

Java小練習(10) -- 亂數小練習

題目要求1:產生六個相鄰兩數不重複的亂數,亂數值介於1~100之間,並印出來。 想法:相鄰兩數不重複,可以用if作判斷;作六次可以用while來控制。
public class RandomTest {

    public static void main(String[] args) {
        byte temp = 0;
        byte count = 0;
        RandomTest ob1 = new RandomTest();
        temp = ob1.getRandom();
        count++;
        System.out.println("第" + count + "次的亂數值為" + temp);

        label:
        while (count < 6) {
            byte _temp = ob1.getRandom();
            if (_temp != temp) {
                temp = _temp;
                count++;
                System.out.println("第" + count + "次的亂數值為" + temp);
                continue label; //再回去取下一個亂數值。
            } else {
                continue label; //甚麼也不做,再取一次。
            }
        }

    }

    //取1-100之間的亂數方法
    public byte getRandom() {
        return ((byte) (Math.random() * 8 + 1));
    }
}
題目要求2: 改進要求1,取六個亂數,但這六個亂數絕對不能重複。 想法:
先做一個100個空間的陣列,依序放1-100
再依序由此陣列提取亂數6次。
提取陣列後便將該欄位清空為零,
從此陣列提取數值時,為零的就不提取,以保證不會重複。
public class ArrayTest1 {

    public static void main(String[] args) {
        int[] data = new int[100]; //作一個100個空間的整數陣列
        for (int i = 0; i < data.length; i++ ) {//依序放1-100
            data[i] = i + 1;
        }
        int count = 0; //用計數器取六次
        while (count != 6) {
            //作一個0~99的亂數當成陣列索引值。
            int random = (int) ( Math.random()*100 ); 
            //取出後就把該值設為0,遇到0就不取值。
            if (data[random] != 0) {
                System.out.println(data[random]);
                data[random] = 0;
                count++;
            }
        }
    }
} 

[轉載]各類塑膠的耐熱性

前幾天老婆叫我找看看2號塑膠是否能夠耐約70~80度C的溫度;我找到了Josh大大所整理的部落格: 塑膠容器編號

耐熱性:

  • 一 號:PET(聚乙烯對苯二甲酸脂)也就是寶特瓶。
  • 特 性:耐熱至70℃,勿長期使用。

  • 二 號:HDPE(高密度聚乙烯)常見於牛奶瓶、果汁瓶。
  • 特 性:耐熱至120℃,是相對穩定的材質。

  • 三 號:PVC(聚氯乙烯)目前的礦泉水瓶。
  • 特 性:耐熱至70℃,環保署已宣布逐步禁用。

  • 四 號:LDPE(低密度聚乙烯)牙膏、洗面乳、乳液瓶等。
  • 特 性:耐熱至80℃

  • 五 號:PP(聚丙烯)便利商店的咖啡瓶,例如x岸咖啡的瓶子。
  • 特 性:耐熱至135℃,是相對穩定的材質

  • 六 號:PS(聚苯乙烯)若是發泡聚苯乙烯即為俗稱之「保麗龍」分為發泡及未發泡兩類。發泡即是一般常見的保麗龍器具,未發泡的如養樂多瓶。
  • 特 性:耐熱至90℃

  • 七 號:其他
  • 特 性:常見材質為聚碳酸脂(PC),耐熱至135℃。某些化妝品使用七號罐。
    具有毒性,請勿重複使用!

結論:
1. 平時應該養成觀察塑膠瓶號碼的好習慣。比較安全的號碼為2號及5號。絕對禁止使用的是1號及3號
2. 高中化學實在是很深哪!我看了這些有機化合物的學名,我還依稀記得分子式應該怎麼畫;不過也是剩下那麼點印象而已;高中化學真難!我最怕化學了!

文章引自:http://blog.jostudio.net/

2009年2月5日 星期四

大小寫互換

很多人換大小寫會用程式語言來作,不過我覺得殺雞焉用牛刀,恰好也該開始練習shell script了!
#!/bin/bash

read -p "請輸入: 1.大轉小 2.小轉大 3.指定轉換副檔名: " choice

case "$choice" in
1) for file in *
do
  lower=`echo "$file" | tr [:upper:] [:lower:]`
  [ "$file" != "$lower" ] &&
  mv "$file" "$lower"
done
echo "轉換完成!"
ls
exit 0
;;

2) for file in *
do
  upper=`echo "$file" | tr [:lower:] [:upper:]`
  [ "$file" != "$upper" ] &&
  mv "$file" "$upper"
done
echo "轉換完成!"
ls
exit 1
;;

3) echo  "輸入欲轉換副檔名:"
read subname
echo  "輸入轉換後的副檔名:"
read newsubname

for file in *.$subname
   do
       mv "$file" "$(basename $file .$subname).$newsubname"
   done
# basename的語法:
# basename /usr/bin/sort       Output "sort".
# basename include/stdio.h .h  Output "stdio".
echo "轉換完成!"
ls
exit 2
;;
*) echo "請輸入1或2。程式終止!"
;;
esac

exit 3
大家試試看吧@! 事實上,我比較喜歡用rename這個指令。利用rename的話,紅色的那行指令可以改寫成:
rename  's/$subname/$newsubname/'  *.$subanme
不過,我手邊現有的機器只有debian跟opensuse 11.1,雖然兩者都有rename指令,不過rename對於opensuse卻沒有效果,也沒有錯誤訊息。查了一下rename是在util-linux套件裡,我也檢查了opensuse確實有安裝util-linux,但就是無效;因此我才選用紅色的code作為各版本通用的script。 OpenSuSE裡的rename用法,以此情況應該改成如下:
rename ".$subname"  ".$newrename"  *.subname
這實在是很不太妙,我竟然要去考慮不同linux間的相同指令的問題!目前只好用basename的的方法來做了!

臉部運動大變身+豬哥亮的歌廳秀

據說自暴其短可以帶來好運!前幾天在北門路的蘋果電腦賣場看到photo booth的拉伸特效,看了實在忍不住多拍幾張;很醜的哩!就讓大家笑笑吧!
## 臉部運動開始 ##
Fig 1.我的人中比李登輝還長吧!(其實比較像喜憨兒)
Fig 2.我的大鋼牙很強壯吧!
Fig 3.我的表情很賤吧!!
Fig 4.我的三角臉!下巴很尖吧!
Fig 4-1. 我失散多年的兄弟!
Fig 5.瞧!瞧瞧我修長的手指跟下巴!(茶)
Fig 6.我的臉像不像復活島的石像呢?(兔齒版)
Fig 6-1. 另一個兄弟比較帥(煙~)
Fig 7.我的臉像不像復活島的石像呢?(人齒版)
Fig 8.我的臉像不像復活島的石像呢?(厚道版)
Fig 8-1. 這個哥哥更帥 Fig 9.別告訴我你沒有吃過萬歲牌堅果!
我也曾經是正常的好男兒的!只是偶爾需要扮演一下豬哥亮賺點外快!
可惜還是輸給孫一美!頭髮不夠長阿!!
糟了,落ㄝ還啦~
## 臉部運動結束 ##
其實,我也有正常的時候啦...
明天還要上班...唉~ 感謝辛苦的攝影師 我的老婆~

2009年2月4日 星期三

[一代聖僧]聖嚴法師

一代聖僧--聖嚴法師於台灣時間2009年2月3日下午四時圓寂了。老和尚瀟灑的來,也瀟灑的去。 我很感謝老和尚所成立的法鼓山,讓我第一次接觸禪宗跟禪學,如此的美麗,也如此的率真。2002年我第一次參加法鼓山所舉辦的大專禪七,聖嚴師父所給我們的教導既風趣又實用,我也在當時馬上就體認到我自己所要的就是這樣的禪法!於是在禪七結束之後皈依,終於成為佛弟子。

我印象中的聖嚴師父總是非常纖瘦,總是覺得師父營養不良;但是他總是有一種安穩的微笑,沉著的態度,說法時專注不二的定,以及帶領我們禪坐時的慈悲。很幸運的,聖嚴法師選擇來到了台灣,弘法給台灣的百姓;也很高興師父並沒有像其他法師一樣如此偏袒中國、偏袒國民黨;無論藍綠,師父都一樣給予懇切的建議,不在乎他是吳伯雄馬英九,也不在乎他是不是貪污的陳水扁,師父所見都是需要幫助的眾生,所有眾生都是未來佛;以此菩薩心境打造人間佛教,真的是台灣的大福氣!

師父走了,我真的很不捨;不過死亡就跟出生一樣自然,都是生命循環的一部分;但願自己臨終之時也能項師父一樣的灑脫自在,遊戲人間!

阿彌陀佛!

請參考:
聖嚴法師對生死的談話

OpenSuSE的vim變黑白了

這真是可怕的事情!黑白的vim就是黑白的人生阿!看看我們的vim:

zypper se vim
S | Name         | Summary                                          | Type    
--+--------------+--------------------------------------------------+-----------
 | avimanager   | Manage your (large) movie (DVD,DivX,(S)VCD) co-> | package 
 | avimanager   | Manage your (large) movie (DVD,DivX,(S)VCD) co-> | srcpackage
 | gvim         | A GUI for Vi                                     | package 
i | vim          | Vi IMproved                                      | package 
i | vim-base     | Vi IMproved                                      | package 
 | vim-data     | Vi IMproved                                      | package 
 | vim-enhanced | A version of the VIM editor which includes rec-> | package   
哦~原來是我們沒有安裝vim增強模式阿,那麼就來裝一下吧!
yast -i vim-enhanced
怎麼回事,還是黑白的阿!!明明在/etc/vimrc裡就有定義syntax on阿!只好再試試看吧!
yast -i vim-data
好險,我的人生終於恢復成彩色的了!真搞不懂opensuse阿!

參考資料:
好用的vim設定
http://www.viemu.com/

2009年2月2日 星期一

在OpenSuSE上安裝JDK以及netbeans

我真是跟不上時代進步,我竟然不知道JDK已經可以直接從網路安裝了@_@

本文介紹兩種jdk安裝方式,一種是使用網路安裝openjdk,一種是手動安裝jdk。

1.透過網路自動安裝openjdk:
首先,先移除原本的java:

zypper remove java-1_6_0-sun Java-1_6_0-plugin

接著,再安裝openjdk:
zypper in java-1_6_0-openjdk java-1_6_0-openjdk-devel java-1_6_0-openjdk-plugin

其中,java-1_6_0-openjdk是jre,java-1_6_0-openjdk-devel是jdk,java-1_6_0-openjdk-plugin是給瀏覽器的plugin。如果你只要jre的環境,請只安裝java-1_6_0-openjdk就好;如果你需要可以開發的環境,請安裝java-1_6_0-openjdk-devel。

假如你所看到的openjdk的版本是1.5或是看不到openjdk,請加入下列repo:

JAVA.repo
-----------------------
[JAVA]
name=JAVA
enabled=1
autorefresh=1
baseurl=http://download.opensuse.org/repositories/Java:/packages/openSUSE_11.1/
path=/
type=rpm-md
keeppackages=0
-----------------------
此時,請到java的網站驗證是否裝了瀏覽器的plugin: 沒錯,我們的jdk版本實在是太舊了(目前最新的版本為1.6.0 update 11,安裝的版本為最早期的1.6.0)。其實java se 6的差異實在不大,如果你沒有追求最新版的慾望,事實上已經建置好java的開發環境了;但是假設你就是想要用最新版的jdk,請參考第二部份的手動安裝。

2.手動安裝JDK
請到sun官網下載JDK 6 Update 11或是JDK 6 Update 11 with NetBeans 6.5(bundle)。安裝bundle比較簡單,這裡介紹分開安裝的方式。安裝以前建議先把openjdk移除,除非你有需要兩個版本的jvm。

zypper rm java-1_6_0-openjdk java-1_6_0-openjdk-devel java-1_6_0-openjdk-plugin
然後先安裝jdk 6 update 11(不建議安裝rpm的那個):
mv jdk-6u11-linux-i586.bin /opt/sun/
sh /opt/sun/jdk-6u11-linux-i586.bin
此時你還需要手動設定jdk的PATH。你需要新增兩行到.profile下:
JAVAHOME=/opt/sun/jdk1.6.0_11/
JDK=/opt/sun/jdk1.6.0_11/bin
export PATH=$PATH:$JDK
接著安裝netbeans:
mv netbeans-6.5-ml-javase-linux-tw.sh /opt/sun/
sh /opt/sun/netbeans-6.5-ml-javase-linux-tw.sh
結果卻出現:
Configuring the installer...
Searching for JVM on the system...
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
sed: -e expression #1, char 52: Invalid range end
Java SE Development Kit (JDK) was not found on this computer
JDK 6 or JDK 5 is required for installing the NetBeans IDE. Make sure that the JDK is properly installed and run installer again.
You can specify valid JDK location using --javahome installer argument.

To download the JDK, visit http://java.sun.com/javase/downloads
暫時設定java的PATH給root吧:
JAVAHOME=/opt/sun/jdk1.6.0_11/
export PATH=$PATH:$JAVAHOME
或是使用參數的方式安裝:
sh /opt/sun/netbeans-6.5-ml-javase-linux-tw.sh --javahome /opt/sun/jdk1.6.0_11
就可以成功啟動安裝程式了。為了方便管理,我一樣把netbeans安裝在/opt/sun底下: 便可以成功啟動netbeans。

3.手動安裝支援java的plugin給瀏覽器
如果不是suse系列的linux,安裝的方式請參照sun的官方教學。如果是java的話,使用官方的教學是沒有用的。suse無論使用任何瀏覽器都會去讀取同一個動態函式庫,因此:

ln -s /opt/sun/jdk1.6.0_11/jre/plugin/i386/ns7/libjavaplugin_oji.so /var/lib/rpm/alternatives/libjavaplugin.so
更多資訊請參考: 簡易佈署java程式 Java on Linux 簡易設定

OpenSuSE skype 無音效問題解決

自從上一篇OpenSuSE 11.1使用感想之後,我發現出現Problem with Audio Playback的問題並非只有opensuse而已。幸好我的問題是最單純的,我的音效卡驅動程式有順利載入,這樣接下來的問題就比較好解決。 首先,先確定音效卡的driver有安裝成功:
lspci -v
你應該會看見:
03:00.0 Multimedia audio controller: ESS Technology ES1969 Solo-1 Audiodrive (rev 02)
Subsystem: ESS Technology Device 8898
Flags: bus master, medium devsel, latency 64, IRQ 19
I/O ports at ec00 [size=64]
I/O ports at e880 [size=16]
I/O ports at e800 [size=16]
I/O ports at e480 [size=4]
I/O ports at e400 [size=4]
Capabilities: 
Kernel driver in use: ESS ES1938 (Solo-1)
Kernel modules: snd-es1938
如果有看到Kernel driver in use的話,便表示有正確的載入驅動程式(或是模組)。或是利用yast看看設定檔,檢查driver有沒有被載入正確: 接著,我們必須手動調整skype的音效裝置: 其中sound in選hw,sound out選plughw,這時你按apply後,做做看音效及撥話測試,應該就會有聲音了!