我很習慣用Vim來作任何有關文字編輯的工作,包含改設定檔、寫程式、寫網頁,甚至是大量改檔名的時候,我也是先用Vim編輯要打的指令之後才送shell處理。Vim真的是文字編輯領域的佼佼者。
閱讀更多…
轉移公告
計劃把 http://blog.hoamon.info/ 文章全部轉移至 http://www.hoamon.info/blog/ 這裡,而本 Blogger 站台的文章近 500 篇,我預計在 2014-12-31 前移轉完畢,完成後 http://blog.hoamon.info/ 將只作代轉服務,一律把舊連結如 http://blog.hoamon.info/index.html 轉成 http://www.hoamon.info/blog/index.html ,敬請舊雨新知互相走告。
何岳峰 敬上
2007年1月23日 星期二
2007年1月22日 星期一
命令列比較好!!(範例篇)
早想寫一篇有關使用命令列及選單介面的效率、任務達成困難性比較。
如果我說使用命令列比較有效率、能達成更困難的工作(do more with less),但是不容易。你相信嗎?
應該是相信吧!畢竟,我都已經強調"不容易"了。只是你一定很難想像黑黑的螢幕加上難按的鍵盤如何工作?
這篇文章就是讓你有一個概念來想像"命令列文化"的博大精深。
在了解命令列及選單介面的差別前,我先來十個命令列技巧:
1.快速刪除層層資料夾中的特定檔案:
[amon@amon amon]$ rm -r `find .|grep "amon[^/]\+.jpg$"`
2.抓取螢幕快照:
三秒後,對整個螢幕拍照
[amon@amon amon]$ sleep 3;xwd -root|xwdtopnm|pnmtojpeg >test.jpg
3.抓取整個網站的內容:
[amon@amon amon]$ wget -c -r http://www.amon.idv.tw/
4.只想聽音樂:
[amon@amon amon]$ mpg123 */*.mp3
[amon@amon amon]$ ogg123 */*.ogg
5.影像處理:
將input.jpg圖檔插入一串文字"測試",然後順時針旋轉45度再轉存為output.png
[amon@amon amon]$ convert -font /mnt/BP/fonts/ngulim.ttf \
>-encoding Unicode \
>-fill black \
>-pointsize 48 \
>-draw 'text 100,200 "'`echo 測試|iconv -f Big5 -t UTF8`'"' \
>-rotate 45 \
>input.jpg output.png
6.Ping目前的區網中,那些電腦是開機的:
[amon@amon amon]$ nmap -sP 192.168.100.1-254|grep "Host"|cut --delimiter=" " -f2
7.抓取unicode.org的gif圖檔(六萬餘筆)
[amon@amon amon]$ perl -e \
>'print "wget -c http://www.unicode.org/cgi-bin/refglyph?24-",sprintf("%04X",$_), \
>" -O ",sprintf("%04X",$_),".gif\n" for (19968..20000)'>tt
[amon@amon amon]$ sh tt
8.分析apache的log檔,得到不同小時的使用人數:
[amon@amon httpd]$ perl -ne 'print $1, "\n" if /\[ [^:]+Sad\d\d).* \]/x' access_log* \
> |sort|uniq -c|perl -ne 'print $2, "\t", $1, "\n" if /(\d+)\s+(\d+)/' >~/x
[amon@amon httpd]$ gnuplot
gnuplot> plot "/home/amon/x"
gnuplot> set output "/home/amon/x.png"
gnuplot> set term png
gnuplot> replot
[amon@amon httpd]$ display /home/amon/x.png
9.快速大量更改檔名,將x-y.jpg改成00002306xxxxyyyy.jpg,例如1-1.jpg改為000023060010001.jpg:
工作上的需要,我得掃瞄大量的日治時期總督府檔案,而其圖檔的命名規則為 000 02306 001 0001 四個區塊,000表總督府檔案,02306表冊號,001表文件件號,0001表頁碼。因為在頁碼部份時常跳號,例如:0003-0009的檔案為大於 A3尺寸,並不用掃瞄,所以無法利用ACDSee之類的軟體幫我作批次改檔名。
一冊的圖檔多為350頁上下,如果在掃瞄時直接鍵入,那麼我得按15*350=5250次的數字鍵,想到就累。於是我在一開始鍵檔名時,只鍵了 1- 1.jpg、2.jpg、3.jpg、4-2.jpg、6.jpg…349-14.jpg、350.jpg等(頁碼在前、件號在後),然後用命令列來改檔名。
[amon@amon pic]$ ls >../t
[amon@amon pic]$ perl -ne '$a = $1 if /-(.*)\./;print $a, "\n"' ../t >../t_l
[amon@amon pic]$ perl -ne '$a = $1 if /^(\d+)[-\.]/;print $a, "\n"' ../t >../t_r
[amon@amon pic]$ paste -d. ../t_l ../t_r >../lr
[amon@amon pic]$ perl -ne 'printf("00002306%03d%04d.jpg\n", $1, $2) if/(.+)\.(.+)/' ../lr >../long_lr
[amon@amon pic]$ paste ../t ../long_lr > ../all
[amon@amon pic]$ perl -ne 'chop;system "mv $_"' ../all
如此一來,我後面的幾百冊都可以直接套用上面7行指令,豈不快哉。
10.終極必殺技-關機:
[root@amon root]$ shutdown -h 21:00
[root@amon root]$ shutdown -h +10
[root@amon root]$ shutdown -k time to maintain
[root@amon root]$ shutdown -r +10
有趣吧!指令列有沒有超乎你的想像呢!!本篇還未完成。畢竟題目說的是"比較好",所以總要寫個對照組吧! 下回我會把它和選單模式來作一個真正的比較。
如果我說使用命令列比較有效率、能達成更困難的工作(do more with less),但是不容易。你相信嗎?
應該是相信吧!畢竟,我都已經強調"不容易"了。只是你一定很難想像黑黑的螢幕加上難按的鍵盤如何工作?
這篇文章就是讓你有一個概念來想像"命令列文化"的博大精深。
在了解命令列及選單介面的差別前,我先來十個命令列技巧:
1.快速刪除層層資料夾中的特定檔案:
[amon@amon amon]$ rm -r `find .|grep "amon[^/]\+.jpg$"`
2.抓取螢幕快照:
三秒後,對整個螢幕拍照
[amon@amon amon]$ sleep 3;xwd -root|xwdtopnm|pnmtojpeg >test.jpg
3.抓取整個網站的內容:
[amon@amon amon]$ wget -c -r http://www.amon.idv.tw/
4.只想聽音樂:
[amon@amon amon]$ mpg123 */*.mp3
[amon@amon amon]$ ogg123 */*.ogg
5.影像處理:
將input.jpg圖檔插入一串文字"測試",然後順時針旋轉45度再轉存為output.png
[amon@amon amon]$ convert -font /mnt/BP/fonts/ngulim.ttf \
>-encoding Unicode \
>-fill black \
>-pointsize 48 \
>-draw 'text 100,200 "'`echo 測試|iconv -f Big5 -t UTF8`'"' \
>-rotate 45 \
>input.jpg output.png
6.Ping目前的區網中,那些電腦是開機的:
[amon@amon amon]$ nmap -sP 192.168.100.1-254|grep "Host"|cut --delimiter=" " -f2
7.抓取unicode.org的gif圖檔(六萬餘筆)
[amon@amon amon]$ perl -e \
>'print "wget -c http://www.unicode.org/cgi-bin/refglyph?24-",sprintf("%04X",$_), \
>" -O ",sprintf("%04X",$_),".gif\n" for (19968..20000)'>tt
[amon@amon amon]$ sh tt
8.分析apache的log檔,得到不同小時的使用人數:
[amon@amon httpd]$ perl -ne 'print $1, "\n" if /\[ [^:]+Sad\d\d).* \]/x' access_log* \
> |sort|uniq -c|perl -ne 'print $2, "\t", $1, "\n" if /(\d+)\s+(\d+)/' >~/x
[amon@amon httpd]$ gnuplot
gnuplot> plot "/home/amon/x"
gnuplot> set output "/home/amon/x.png"
gnuplot> set term png
gnuplot> replot
[amon@amon httpd]$ display /home/amon/x.png
9.快速大量更改檔名,將x-y.jpg改成00002306xxxxyyyy.jpg,例如1-1.jpg改為000023060010001.jpg:
工作上的需要,我得掃瞄大量的日治時期總督府檔案,而其圖檔的命名規則為 000 02306 001 0001 四個區塊,000表總督府檔案,02306表冊號,001表文件件號,0001表頁碼。因為在頁碼部份時常跳號,例如:0003-0009的檔案為大於 A3尺寸,並不用掃瞄,所以無法利用ACDSee之類的軟體幫我作批次改檔名。
一冊的圖檔多為350頁上下,如果在掃瞄時直接鍵入,那麼我得按15*350=5250次的數字鍵,想到就累。於是我在一開始鍵檔名時,只鍵了 1- 1.jpg、2.jpg、3.jpg、4-2.jpg、6.jpg…349-14.jpg、350.jpg等(頁碼在前、件號在後),然後用命令列來改檔名。
[amon@amon pic]$ ls >../t
[amon@amon pic]$ perl -ne '$a = $1 if /-(.*)\./;print $a, "\n"' ../t >../t_l
[amon@amon pic]$ perl -ne '$a = $1 if /^(\d+)[-\.]/;print $a, "\n"' ../t >../t_r
[amon@amon pic]$ paste -d. ../t_l ../t_r >../lr
[amon@amon pic]$ perl -ne 'printf("00002306%03d%04d.jpg\n", $1, $2) if/(.+)\.(.+)/' ../lr >../long_lr
[amon@amon pic]$ paste ../t ../long_lr > ../all
[amon@amon pic]$ perl -ne 'chop;system "mv $_"' ../all
如此一來,我後面的幾百冊都可以直接套用上面7行指令,豈不快哉。
10.終極必殺技-關機:
[root@amon root]$ shutdown -h 21:00
[root@amon root]$ shutdown -h +10
[root@amon root]$ shutdown -k time to maintain
[root@amon root]$ shutdown -r +10
有趣吧!指令列有沒有超乎你的想像呢!!本篇還未完成。畢竟題目說的是"比較好",所以總要寫個對照組吧! 下回我會把它和選單模式來作一個真正的比較。
版本控制系統:svn(subversion)
不管你是寫程式還是系統設定檔的管理,在在都是一門學門,尤其是你得和其他人一同工作的時候。如果你是把工作完成的程式檔壓縮起來寄給別人的話,那你一定得聽聽什麼是版本控制。
目前市面上,比較有名(而且是open source)的版本控制系統有兩種:cvs及subversion。之前我也是用cvs的,不過在我看了這一篇文章後,我就把cvs丟了。
版本控制系統不外乎要解決的是三個地方的文件(含純文字檔、圖檔等)合併問題,依術語來說就是檔案庫、你的工作複本及別人的工作複本。
檔案庫永遠是文件最後該放置的地方,而你的工作複本一開始是從檔案庫來的,經過你的修改,最後再送回檔案庫中;而別人的工作複本也是一樣是從檔案庫來的,也是經由別人的修改,最後再送回檔案庫中。
而版本控制系統的工作就是在於能合諧地整合你所修改的工作複本及別人修改的工作複本,讓他們能在送進檔案庫時不會蓋掉任一方的成果。
說到這裡,你一定很心動了吧!畢竟當你只能用copy的方式作版本控制時,經常發生的蓋檔問題絕對讓你到現在還記憶猶新。
所以,請花個30分鐘來看看這一篇文章吧。距離你不寫程式的年紀,應該還有個五~十年的光景,早學早超生呀!
在使用svn時候,有二個觀念是很重要的。
一、詳實的送交註解
一定要詳實地寫上送交註解(commit comment),不要只是寫:「又更新版本了」、「解決一個bug」…等等之類無用的訊息,應該是「解決$input變數在$_GET ['input']=''時不能賦值的問題」、「給grace--在樣版中的$greeting應該定義為$hello,因為…」…等等之類的訊息。
二、看別人寫的commet
使用者在svn update前應該先查出自已目前的版本號,查目前版本號的方法如下,最大的號碼即為你目前的版本號
# svn status -N -v
然後在svn update後,把原本版本號到最新版本號之間的送交註解看一下。例如:原本你的工作複本版本號為13,當你修改過後要送交之前得作一次svn update,版本號跳為17,那你這時候應該要作一次看comment的指令:
# svn log -r 13:17
或是
# svn log -r 13:17 -v
先看看別人之前改了什麼,然後你自已評估與目前你所修改的程式流程有沒有衝突,例如:別人在16版的時候把$content[_msg]變數改為 $content[_lang]變數,那麼如果你有使用$content[_msg]的話,你就應該先改好手邊的工作複本,再作svn commit。
如果你覺得看comment不夠清楚,那麼直接比較一下程式碼到底有那裡是不同,指令是:
# svn diff -r 16
上面的指令會比較第16版與你手邊已修改但還未送交的版本作比較,如果你只想比較單一檔案的話,指令是:
# svn diff -r 16 iLovePerl.php
直接把檔案名帶進出。
有時候你個人的commit周期太慢了(可能因為一個bug一直抓不出來),
那你還是要在未上傳檔案庫前,經常地(至少是一天一次)觀看遠端檔案庫的版本情況,
像是你的工作複本到遠端檔案庫之間的送交註解,其指令如下:
# svn log -r BASE:HEAD
這樣才不會與其他人的距離差太遠,否則等你要commit時,才來調整你的程式碼,
這又太慢了。
有時候,在svn所控制的專案中,你有不想作版本控制的檔案,那該這麼作呢!
像是資料庫的設定檔,這個東西,每個程設師在開發狀態時,可能用的都是臨時性的資料庫,一個人一種設定,如果每一次commit或update後都把別人用的或是自己用的給重設了,
那是件很麻煩的事,所以呢,我們使用svn:ignore性質來解救我們,方法如下,後來的Config代表的是一個資料夾,是你所想忽略的檔案所在的那一個資料夾,如果你想忽略的檔案是在現在的目錄中,那就把 Config 換成 .
# svn propedit svn:ignore Config
然後它會進入stdin的模式,你直接打檔名進去即可,像是
# svn propedit svn:ignore Config
DB.config
然後按下 Ctrl+D即可。請記住DB.config是在Config資料夾中的檔案喔,而且DB.config檔不應該送進svn add中喔
=== 後記 ===
現在我已經改用 Mercurial/Hg(http://hoamon.blogspot.com/2009/03/from-subversion-to-mercurial.html) 了,最大的優點是可離線操作,不像 svn 如果沒有中央伺服器,有些工作就沒辦法作了。
目前市面上,比較有名(而且是open source)的版本控制系統有兩種:cvs及subversion。之前我也是用cvs的,不過在我看了這一篇文章後,我就把cvs丟了。
版本控制系統不外乎要解決的是三個地方的文件(含純文字檔、圖檔等)合併問題,依術語來說就是檔案庫、你的工作複本及別人的工作複本。
檔案庫永遠是文件最後該放置的地方,而你的工作複本一開始是從檔案庫來的,經過你的修改,最後再送回檔案庫中;而別人的工作複本也是一樣是從檔案庫來的,也是經由別人的修改,最後再送回檔案庫中。
而版本控制系統的工作就是在於能合諧地整合你所修改的工作複本及別人修改的工作複本,讓他們能在送進檔案庫時不會蓋掉任一方的成果。
說到這裡,你一定很心動了吧!畢竟當你只能用copy的方式作版本控制時,經常發生的蓋檔問題絕對讓你到現在還記憶猶新。
所以,請花個30分鐘來看看這一篇文章吧。距離你不寫程式的年紀,應該還有個五~十年的光景,早學早超生呀!
在使用svn時候,有二個觀念是很重要的。
一、詳實的送交註解
一定要詳實地寫上送交註解(commit comment),不要只是寫:「又更新版本了」、「解決一個bug」…等等之類無用的訊息,應該是「解決$input變數在$_GET ['input']=''時不能賦值的問題」、「給grace--在樣版中的$greeting應該定義為$hello,因為…」…等等之類的訊息。
二、看別人寫的commet
使用者在svn update前應該先查出自已目前的版本號,查目前版本號的方法如下,最大的號碼即為你目前的版本號
# svn status -N -v
然後在svn update後,把原本版本號到最新版本號之間的送交註解看一下。例如:原本你的工作複本版本號為13,當你修改過後要送交之前得作一次svn update,版本號跳為17,那你這時候應該要作一次看comment的指令:
# svn log -r 13:17
或是
# svn log -r 13:17 -v
先看看別人之前改了什麼,然後你自已評估與目前你所修改的程式流程有沒有衝突,例如:別人在16版的時候把$content[_msg]變數改為 $content[_lang]變數,那麼如果你有使用$content[_msg]的話,你就應該先改好手邊的工作複本,再作svn commit。
如果你覺得看comment不夠清楚,那麼直接比較一下程式碼到底有那裡是不同,指令是:
# svn diff -r 16
上面的指令會比較第16版與你手邊已修改但還未送交的版本作比較,如果你只想比較單一檔案的話,指令是:
# svn diff -r 16 iLovePerl.php
直接把檔案名帶進出。
有時候你個人的commit周期太慢了(可能因為一個bug一直抓不出來),
那你還是要在未上傳檔案庫前,經常地(至少是一天一次)觀看遠端檔案庫的版本情況,
像是你的工作複本到遠端檔案庫之間的送交註解,其指令如下:
# svn log -r BASE:HEAD
這樣才不會與其他人的距離差太遠,否則等你要commit時,才來調整你的程式碼,
這又太慢了。
有時候,在svn所控制的專案中,你有不想作版本控制的檔案,那該這麼作呢!
像是資料庫的設定檔,這個東西,每個程設師在開發狀態時,可能用的都是臨時性的資料庫,一個人一種設定,如果每一次commit或update後都把別人用的或是自己用的給重設了,
那是件很麻煩的事,所以呢,我們使用svn:ignore性質來解救我們,方法如下,後來的Config代表的是一個資料夾,是你所想忽略的檔案所在的那一個資料夾,如果你想忽略的檔案是在現在的目錄中,那就把 Config 換成 .
# svn propedit svn:ignore Config
然後它會進入stdin的模式,你直接打檔名進去即可,像是
# svn propedit svn:ignore Config
DB.config
然後按下 Ctrl+D即可。請記住DB.config是在Config資料夾中的檔案喔,而且DB.config檔不應該送進svn add中喔
=== 後記 ===
現在我已經改用 Mercurial/Hg(http://hoamon.blogspot.com/2009/03/from-subversion-to-mercurial.html) 了,最大的優點是可離線操作,不像 svn 如果沒有中央伺服器,有些工作就沒辦法作了。
公私錀應用在網路通訊上(https部份)
什麼是https呢?一般如果你有過線上刷卡的經驗,那麼你就有使用https的機會了,平常你瀏覽網頁時,網址的開頭都是http,這代表你是使用 http協定與遠端的網頁伺服器作網頁要求的動作,然而http協定是不會把你跟網頁伺服器說的話作加密的動作的,所以,掌管你網路的系統管理員絕對有能力及機會知道你和伺服器要求什麼樣的網頁(不要懷疑,hinet、seednet的管理員絕對是可以看到的,只是要不要而已),像是你看過那些美美的圖片啦、什麼人寄了什麼的信給你呀(當你使用yahoo的webmail時)、發表什麼內容的文章…等。所以如果你在線上刷卡時,還是使用http協定的話,那我想網路管理員應該會更有錢點。
在傳送極度機密資料時,都應該使用https協定,這也是銀行會在提供線上刷卡時必須使用https協定讓使用者刷卡的原因。本討論區也是使用了 https協定,主要有兩個理由,一是筆者的帳號/密碼都是一樣地,如果你過濾出這個ops討論區中我所使用的帳號/密碼,那也知道我所有管理機器的密碼了,二是我不想讓各地的proxy server快取這個ops討論區的內容,這個討論區我希望是小眾的、專屬於會員的。
https的使用是很簡單,像ssh的tips一樣,先把公私錀生出來,然後放對位置,再重新啟動你的網頁伺服器即可啦。
首先生成公私key,
# openssl req -new > your_define.csr
過程中會要求你輸入your_define.csr的密碼,先隨便輸入4個字以上的密碼,這個your_define.csr只是設定過程中的產物,最後的成品與它無關,所以它的密碼也就隨便設吧!接著輸入你的國家代碼、州名(省名)、縣市名、組識名、單位名、主機名、系統管理員email等。最後的兩個項目,我也不知道該輸入什麼,但是沒輸也沒有關係。
# openssl rsa -in privkey.pem -out your_define.key
輸入剛設定your_define.csr的密碼來產生your_defice.key
# openssl x509 -in your_define.csr -out your_define.crt -req -signkey your_define.key -days 3560
-days 3650表這個公私錀會在10年才過期。
到這裡表示公私錀已成功完成了,接下來更改你的/etc/httpd/conf.d/ssl.conf。
......
......
SSLCertificateFile /where_you_stored/your_define.crt
SSLCertificateKeyFile /where_you_stored/your_define.key
......
......
這個檔在你安裝mod_ssl.xxx.rpm後才會出現。
最後重新啟動你的apache就可以了。
注意:使用apache的老手可能會很習慣一個ip設很多虛擬網站,但是在https上,因為ssl layer比http layer還要早溝通完畢,所以一個ip只能使用一對公私錀,這在你有兩個以上的虛擬網站時,如果你的公私錀名字定為a.hoamon.info,那當使用者連到b.hoamon.info時,會出現「這個憑證名字為a.hoamon.info,但你所要連線的網站是b.hoamon.info,有可能是有人要截斷你與伺服器之間的通訊,你確定要繼續連線嗎?」
這個問題目前是無解的。只有多設幾個ip才行。
在傳送極度機密資料時,都應該使用https協定,這也是銀行會在提供線上刷卡時必須使用https協定讓使用者刷卡的原因。本討論區也是使用了 https協定,主要有兩個理由,一是筆者的帳號/密碼都是一樣地,如果你過濾出這個ops討論區中我所使用的帳號/密碼,那也知道我所有管理機器的密碼了,二是我不想讓各地的proxy server快取這個ops討論區的內容,這個討論區我希望是小眾的、專屬於會員的。
https的使用是很簡單,像ssh的tips一樣,先把公私錀生出來,然後放對位置,再重新啟動你的網頁伺服器即可啦。
首先生成公私key,
# openssl req -new > your_define.csr
過程中會要求你輸入your_define.csr的密碼,先隨便輸入4個字以上的密碼,這個your_define.csr只是設定過程中的產物,最後的成品與它無關,所以它的密碼也就隨便設吧!接著輸入你的國家代碼、州名(省名)、縣市名、組識名、單位名、主機名、系統管理員email等。最後的兩個項目,我也不知道該輸入什麼,但是沒輸也沒有關係。
# openssl rsa -in privkey.pem -out your_define.key
輸入剛設定your_define.csr的密碼來產生your_defice.key
# openssl x509 -in your_define.csr -out your_define.crt -req -signkey your_define.key -days 3560
-days 3650表這個公私錀會在10年才過期。
到這裡表示公私錀已成功完成了,接下來更改你的/etc/httpd/conf.d/ssl.conf。
......
SSLCertificateFile /where_you_stored/your_define.crt
SSLCertificateKeyFile /where_you_stored/your_define.key
......
......
這個檔在你安裝mod_ssl.xxx.rpm後才會出現。
最後重新啟動你的apache就可以了。
注意:使用apache的老手可能會很習慣一個ip設很多虛擬網站,但是在https上,因為ssl layer比http layer還要早溝通完畢,所以一個ip只能使用一對公私錀,這在你有兩個以上的虛擬網站時,如果你的公私錀名字定為a.hoamon.info,那當使用者連到b.hoamon.info時,會出現「這個憑證名字為a.hoamon.info,但你所要連線的網站是b.hoamon.info,有可能是有人要截斷你與伺服器之間的通訊,你確定要繼續連線嗎?」
這個問題目前是無解的。只有多設幾個ip才行。
訂閱:
文章 (Atom)