2010年3月26日

[Chart Control 技巧篇] 改變特定軸線的樣式

前陣子坎尼看到論譠上問了標題這個問題
想說試著來解解看 (以前沒遇過這個需求 :D
另外本篇來提供一下坎尼平常思考問題的方式

I.問題思考方式

先來看一下問題
「設定Y軸的25是一條有顏色的線(有點類似標準線的意思),
其它Y軸的線正常顯示
」
特定線段顏色不同 坎尼先擬定了幾個主要的方法:
  • 利用 Custom Label 直接設定特定線段的樣式
  • 開啟 Secondary Y 則是想用其他線段來蓋掉原本的線段

    所以坎尼開啟了 Visual Studio,開始測試相關屬性
    (這邊可以用心智圖之類的工具來輔助思考,如上圖)

    從 Custom Label 的經驗得知,並無法只設定特定格線的樣式
    格線屬性為整個 Y 軸所共用
    但可以修改 GridTicks 屬性,使想要的格線顯示出來
    ChartXX2 
    經由上面的經驗,坎尼想到了 ChartArea 預設還有另一條軸線
    如果同時打開兩邊的軸線,應該其中一邊的樣式會蓋掉另外一邊吧?

    坎尼打開 Secondary Y ,加入 Custom Label 實驗出來的成果
    Bingo!!!
    Secondary Y 軸的樣式會蓋住主軸線的樣式,測完收工!!!

    II.範例

    上面已經將過程說明,所以這邊放一下實際的範例圖片吧

    打開 ChartArea 的 Axes 集合
    調整 Secondary Y 的 MajorGrid 線條樣式
    CharX2建立 Custom Label,並設定顯示位置為 25
    將 GridTicks 屬性設定成 Gridline,讓 Chart 只顯示自訂 Label 以及它的格線
    CharX3實際設定完成後的原始碼
    ChartXX1執行畫面
    CharX

    III.小結

    其實坎尼寫到這邊發現,用 MinorGrid 是否也能達成此項需求?
    這邊就賣個關子,不公布答案,讀者們有興趣可以試試看 :D

    思考問題的過程其實很有趣
    能建立起一套自己的思考方式,其實對自己的未來很有幫助 :P
  • 讓 tar 檔解壓縮出來的檔案的 modification time 變成執行解壓縮指令的當下時間 (用於以解壓縮 tar 檔的方式更新程式時)

    嗯 … 標題有點囉嗦,在系統上要更新程式時,常常會先將欲更新的程式,重點在於在下指令解壓縮 tar 檔時,如果只用一般常見的下法:tar zxvf xxx.tar.gz 的話,那麼解壓縮出來的檔案的 modification time 會維持當初打包 tar 檔的時間,而不會是執行解壓縮 tar 檔的時間,在資安稽核要求很嚴謹的環境中,以上的狀況是不被接受的。

    要讓 tar 檔解壓縮出來的檔案的 modification time 被修正為執行指令的當下時間很簡單,參考 tar 指令的 man page:

    -m, --touch, --modification-time

    don't extract file modified time

    此處渴看到關鍵字「touch」,再查一下 touch 指令的 man page:

    touch [OPTION]... FILE...

    Description

    Update the access and modification times of each FILE to the current time.

    所以說,爾後解壓縮 tar 檔時只要下如此的指令:tar zxvfm xxx.tar.gz,那麼解壓縮出來的檔案的 modification time 就會是執行指令的當下時間啦!(看起來是 tar 這支程式會自動幫你 touch 壓縮檔內的所有檔案/目錄)

    PS. 昨天為了這個需求,還寫了個 4、50 行的 Perl 程式 (先建立 temp 目錄 –> 把原始 tar 檔複製到 temp 目錄 –> 在 temp 目錄解壓縮 –> 把解壓縮出來的所有檔案/目錄 touch 一遍 –> 再壓縮成一個新的 tar 檔 –> 把新的 tar 檔複製到真正的目的資料夾 –> 在目的資料夾解壓縮 –> 回頭刪掉 temp 目錄),現在看起來真的是蠢斃了 =.= 幸好隔了一天就發現 -m 這個參數 … 可見認真的讀完 man page 是多麼重要的事情!

    不過在寫 Perl 的過程中又多學到了一些處理檔案、目錄的技巧,例如 mkdir -p 可以自動幫你建立完整的目錄階層;cp -a 類似沒有加上 -m 的 tar,效果等同於幫指定目錄建立另一個名稱不同的目錄,再把指定目錄下的所有子目錄和檔案複製到新目錄中,但是新目錄下的檔案 modification time 跟原目錄是一樣的 …

    2010年3月22日

    [MySQL] 設定資料庫定期自動備份

    上週開始持續調整以 Joomla 架設的資產管理系統,其中一個需求是自動定期備份 DB,如此便可追蹤這些設備在一段時間內的變化(其實我還是覺得如果要作版本控管的話,用 svn 或者 git 之類的版本控管軟體會更好…),當發生不幸的意外時也才能迅速的將寶貴的資料還原。

    由於 Joomla 的資料都存在 MySQL DB 中,因此今天就 survey 了一下讓 MySQL 定期排程備份的作法。

    I.以 shell script 呼叫 mysqldump 執行備份,將此 script 寫入 crontab 排程中

    參考資料:MySQL 備份 shell script。這 script 的核心非常簡單,只有一行而已 (其他更 fancy 的工具應該也是呼叫這個 MySQL 內建的 dump 工具):

    mysqldump -u $db_user -h $db_host -p$db_passwd $db | $GZIP -9 > "$backup_dir/backup.0/$time.$db.gz"

    而 crontab 的編寫也是玩 Linux / Unix 的基本功,可參考:鳥哥的 Linux 私房菜-第十六章、例行性工作排程 (crontab)。以這個方法來備份 MySQL 大概是最不求人、也相當普遍的作法。

    II.利用 Navicat full version 來作

    參考資料:[教學] MySQL 定期自動備份。這是一個可安裝在 Windows / Linux / Mac OS X 平台的 client 端軟體,安裝和操作都相當方便 (畫面蠻漂亮的)。雖然說 Navicat 有推出一個免費的 Navicat Lite,但是免費版連手動執行 backup 都做不到呀!因此它就很遺憾的出局了,但是有錢買來用的話應該相當好用 (最貴的授權要台幣一萬出頭),看來這軟體也是相當的知名。

    III.利用 phpMyBackupPro (pMBP) 來作

    2010-03-23 補充:[網管人雜誌] MySQL 專用備份工具-phpMyBackupPro (長篇的詳細說明)

    參考資料:Web 介面的 MySQL 備份工具-phpMyBackupPro, 官方網站下載頁面在這裡,這是個 host 在 SourceForge 的 open source 專案,所以是免費的!安裝的過程非常簡單,在 Windows 平台上只要把解縮後的 phpMyBackupPro 資料夾複製到 Apache 的根目錄下即可。

    2010-03-23 補充:在 Linux 平台上安裝也很簡單,只要把資料夾 export 及檔案 global_conf.php 設定權限為 0777 就可以了。執行身分為 apache。

    其中最重要的一點是,若 DB 中有儲存中文資料,要依照論壇中 slimn 前輩提供的修改方式來調整,經過測試確實有效 (Windows 平台 OK, 目前在 Linux 測試機上仍為亂碼 [2010-03-23]):

    pMBP_TraditionalChineseTest

    以下補充教學文章中沒有特別說明的設定畫面。

    在 configuration tab中,可設定僅備份指定 DB:

    pMBP_configurationSettings

    在 backup tab 中,記得要手動選取欲執行備份的 DB:

    pMBP_BackupSettings

    在 backup tab 中可設定是否要壓縮備份產出的 .sql 檔,有 gzip / zip 格式:

    pMBP_BackupCompressionSettings

    在 schedule backup tab 中,可設定自動執行備份的週期:

    pMBP_scheduleBackupSettings
    包括每小時、每6小時、每12小時、每天、每週、每月等等週期。

    在 schedule backup tab 中,也可自訂定期備份 php 檔的檔名:

    pMBP_scheduleBackupSettings_SaveNewScriptFile

    在 import tab 中,若已經執行過備份,則可觀看指定備份檔(.sql) 的各項資訊:

    pMBP_import_viewBackupFileInfo 包括執行備份的日期時間、DB Name、file size 等。

    關於 schedule backup:

    在Web 介面的 MySQL 備份工具-phpMyBackupPro一文中提到,schedule backup 感覺不太實用,因為排程備份的作法是一段 php 程式碼,而phpMyBackupPro 只是負責幫你產出這段 code,必須要另外加工讓這段 code 能夠定時執行 (不管是利用網頁的 META Refresh 或者在 crontab 中定期用 wget 去 request 這個 php 網頁)。但我覺得 phpMyBackupPro 還可提供備份後自動上傳到 FTP、自動寄送 mail 等等,而且檢視/還原 backup 檔案的介面也十分簡便,安裝和設定也很容易就可以上手,還是很不錯用的啦!

    2010年3月17日

    [Shell Script] 批次修改使用者的密碼有效期限 - V1

    最近公司在做資訊稽核,其中有一塊牽涉到主機上的帳號管理。根據公司的資安規範,每個使用者帳號 (系統內建帳號除外) 必須符合以下限制:
    1. 密碼長度不得小於6個字元
    2. 密碼有效期為90天 (也就是每90天就要變更一次密碼的意思)
    3. 不得使用三代以內的密碼
    4. 密碼不得與帳號相同
    除了第四點是系統內建,不需要調整設定以外,其餘幾項都需要調整系統設定 (Solaris 只要修改系統內建的設定檔即可;針對第1和第3項要求,Linux 則必須要使用 PAM 模組的設定來達成,下次再撰文說明),本文先針對第二點進行說明。
    要設定「密碼有效期為90天」並不困難,不管在 Solaris / Linux 上都只要透過 passwd 指令或者 chage 指令即可完成,但由於我覺得 chage 指令很容易使用,查詢所得的結果也很容易閱讀,所以這次就以 chage 來實作。
    有關 chage 指令的用法,除了參考鳥哥的網站,也可以直接下 man chage 指令來查詢內建的 man page,我用的指令如下:
    chage -I 1 M 90 -W 30 [username] chage -d 2010-03-17 [username]
    (第二個指令是為了避免設定好第一個指令以後,所有系統上 90 天內不曾修改密碼的使用者下次登入系統時都要重新設定密碼,因此把「最後一次修改密碼」的日期改為今天)
    設定完畢之後,再下 chage –l [username] 指令 (英文的 l) 即可查詢該使用者的帳號狀態。
    OK, 既然 chage 指令這麼簡單,那本文有甚麼好講的呢?如果只需要在單一主機上對少數幾個帳號作如此的設定,當然是直接下幾個指令就搞定,問題是這次需要修改的主機超過 50 台,每台主機上面又有一大堆帳號,真要這樣下指令的話會瘋掉!(而且還有第1和第3項要求要作到,那又是另外兩行 Perl 程式) 所以我就把這些機械化的動作寫成一個 script 啦!
    第一步:詢問使用者 chage -d 要使用的日期參數:
    echo “set Last password change day (YYYY-MM-DD): “ read lDays #把使用者輸入的參數存到 $lDays 變數中
    接下來判斷使用者輸入的字串是否符合 YYYY-MM-DD 的格式:
    syntaxOK=`echo $lDays | perl –ne ‘print “OK” if /^\d{4}-\d{2}-\d{2}/’` (`` 是 backtick,不是單引號哦~)
    if [ "$syntaxOK" != "OK" ]; then    echo "Wrong syntax! Usage: YYYY-MM-DD"    exit fi
    這裡用 perl 來寫 regular expression 會比用 shell script 簡單很多,shell script 要這樣寫 (因為沒有支援 \d 這樣的表示法,而且也不支援 {4} 的寫法):
    syntaxOK=`echo $lDays | grep "^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$"`
    神奇的是用 perl 的話不用加上「$」來限制結尾要是 2 個數字,就自然可以判斷出「1111-11-111」是不符合 pattern 的,但是用 shell script 中的 grep 的話就要 (用 egrep 還是要加上「$」)。
    第二步:列出系統中所有的使用者,除了系統內建帳號以外:
    我參考的是 Listing all users on the system 一文,但是在 awk 的主程式中加上 regular expression 的判斷:
    for name in $(awk 'BEGIN{FS=":"} { if($3 ~ /^5[0-9][0-9]/) {print $1}}' < "$PASSWORD_FILE" )
    利用這個 pattern 可以過濾出第三欄 ($3) 的值是「5xx」(xx 為數字) 的資料,且印出第一欄 ($1)。
    第三步:過濾 uid > 500 的帳號中,屬於系統帳號 or 給程式使用的帳號:
    一般來說 uid < 500 的是保留給系統使用的帳號,但 uid > 500 的帳號中仍有可能存在單純給程式使用的帳號 (e.g., 給 FTP / scp 使用),因此需要進一步過濾。我的作法世新增一個 AccountExcluded.txt 檔案,以一行一個帳號的方式,將欲排除的帳號寫入這個檔案,接下來用一個迴圈就可以比對:
    accountExcluded=`cat ./AccountExcluded.txt` excluded="0" for exclude in $accountExcluded do      if [ $name = $exclude ]; then             excluded="1"      fi done
    第四步:執行 chage 指令
    到了這個步驟才是整個 script 的核心,對於每個不在 AccountExcluded.txt 檔案中的帳號,只要在以上的迴圈中執行以下兩行即可:
    chage -M 90 -W 30 $name chage -d $lDays $name
    整個 script 其實就只有這樣而已,為了避免更動到系統帳號才額外加了一堆有的沒的程式碼 (為了寫 log 又另外加了一堆),在這次練習的過程中,發現還是寫 RegExp 最好玩 (awk 也很有趣),其他的程式碼都挺無聊的。
    這個 script 未來還有很多可以 enhance 的地方,依照重要性由高到低排列:
    1. 在本機上登入所有需要修改的主機,將本機的 shell script 檔&設定檔複製到所有的主機上執行 (不然一台一台的登入也是很累人的)。將這個架構建立起來以後,未來有遇到類似要再每台主機上調整設定的需求,就可按照同樣的模式寫成一個 script 來執行。
    2. 加強 YYYY-MM-DD 的判斷,找找看有沒有轉換成 Date 之類型態的方式可用,順便避免 2/29 的問題。
    3. 把讀取兩次 /etc/passwd 的寫法改成只讀取一次,第一次讀出資料以後存到一個 array 裡面就好。
    4. 加強過濾 /etc/passwd 檔案時使用的 regular expression,雖然目前實務上接觸到的主機還不至於帳號多到 uid > 600 或者更高,但可以當作一個練習 regular expression 的機會。
    有興趣參考完整原始碼的朋友請到這裡下載 (V1)。

    參考:[2010-12-13] [Shell Script] 批次修改使用者的密碼有效期限 - V2

    [輕鬆學會 Chart Control] 利用 Generic Handler 提供 Chart 圖片資訊

    有時候你的 Team Member 想要使用 Chart 來令資訊圖形化
    但卻不會用 MS Chart Control 或是其他圖表工具時該怎麼辦呢?
    好死不死他又來拜托你
    此刻本篇範例就派的上用場啦~

    I. 準備

    首先,在 Web 專案中建立 Generic Handler 的檔案
    ghc00先引用 System.Web.UI.DataVisualization.Charting Namespace
    ghc01 
    接著進入 class 中撰寫動態建立 Chart Control 的方法ghc02 設定完樣式和屬性之後,可從外部取得資料來源再進行繫結
    再利用 Chart.SaveImage 的方法,將圖片丟給 OutputStream 即可
    (不知道這個方法怎麼用的人,可以參考 這篇)

    II. 使用方式

    「雖然寫好了產生 Chart 圖片的 Code,但是該怎麼使用呢? 」

    方法很簡單,只需在 Web 頁面上加入 img 的控制項
    再將來源指定給寫好的 .ashx 即可
    ghc03 
    打開原始檔就能看到來源其實是 .ashxghc04

    III. 結論

    利用上述的方式,就可以簡單的分工撰寫頁面及圖形

    參考來源:
  • HttpResponse.OutputStream Property
  • Chart.SaveImage Method
  • 2010年3月15日

    自行製作 SecureCRT Portable 版

    SecureCRT 是我日常工作中不可或缺的工具 (之前介紹過 SecureCRT Solaris/Linux console 的顏色配置),剛好上週聊天時同事提到:「我都盡量用 portable 軟體,這樣做壞事才不會被抓到比較方便」,經過一番 survey ,發現可以把系統中已經安裝的 SecureCRT 改成 Portable 版,以下以 SecureCRT 6.0.1 為例 (5.x 版的改法也差不多,主要是設定檔的資料夾名稱不同):
    步驟一:先備份 SecureCRT 的設定檔
    設定檔位置可從 Options --> Global Options 中,General 類別中右下角的
    Configuration folder 來查 (5.x 版的設定檔資料夾名稱為 Sessions)
    01.1
    步驟二:首先把目前電腦中已安裝的 SecureCRT 資料夾複製到目的地
    (e.g., 桌面\SecureCRT)
    01
    步驟三:把SecureCRT 的設定檔複製到目的地 (e.g., 桌面\SecureCRT\Config)
    完成以後,桌面/SecureCRT 資料夾中的內容應該長的像下面這樣 (C:\Documents and Settings\user\桌面\SecureCRT):
    01.12
    步驟四:修改 Config 資料夾下的 SSH2.ini 檔,把 S:"Host Key Database Location" 的值 (此為 SecureCRT 儲存 Known Hosts 資料夾的位置) 改為新的位置,例如:
    C:\Documents and Settings\user\桌面\SecureCRT\Config\Known Hosts
    08
    步驟五:新增一個捷徑 (以後都由此捷徑啟動 SecureCRT),在「項目的位置」中格式為:"新的 SecureCRT 執行檔位置" /F "新的 SecureCRT 設定檔位置",例如:
    "C:\Documents and Settings\user\桌面\SecureCRT\SecureCRT.exe" /F "C:\Documents
    and Settings\user\桌面\SecureCRT\Config"
    說明:
    1. 完整路徑加上雙引號「" "」比較保險,可避免資料夾名稱含有中文或空白時造成問題
    2. /F 參數可強迫 SecureCRT 啟動時去讀取指定位置的設定檔,否則 SecureCRT 會試圖建立 C:\Document and Settings\user\Application Data\VanDyke (WinXP) or C:\ProgramData\VanDyke (Win7) 資料夾 (Vista 的位置大概差不多)。
    這樣就ok了,接下來可以把已安裝的 SecureCRT 移除,再執行步驟五新增的捷徑來驗證看看是否成功。

    (也可以把 \桌面\SecureCRT 整個資料夾放到隨身碟中帶著走)
    經過測試,發現執行時 SecureCRT 仍會在 Application Data / ProgramData 中建立 VanDyke 資料夾 (其中有 Known Hosts 資料夾),但是儲存 Known Hosts 的位置仍然為 SSH2.ini 中所指定的位置。
    參考資料:VanDyke Support – Running SecureCRT from a USB Flash Memory Drive
    2010.03.17 補充:經過實測,若第一次安裝 SecureCRT 時有經過破解,在製作 portable 版本時就不用製作上述參考資料中的第三點所提到的 SecureCRT.lic 檔案。


    2012.07.15 補充:因為 SecureCRT 需購買授權方可使用,另外可考慮 MTPuTTY,好處在於免安裝,且設定檔就存在與執行檔相同的目錄中,方便備份(不像 PuTTY 是將設定檔存在 registry 中,要備份很麻煩)。

    2010年3月13日

    [輕鬆學會 Chart Control] 將圖表匯出至 Excel - 使用NPOI

    好久沒開 Chart Control 議題了
    剛好前陣子 Codeplex 出現可以輕鬆建立 Excel 檔案的 Library-NPOI
    於是坎尼想說研究一下,看能不能把 Chart Control 匯出圖片到 Excel 中
    沒想到只花了不到1小時就研究出來了,真的是很簡單 :D

    I.準備

    首先是下載 NPOI Library,並將它加入至專案中
    其他相關說明可以參考 MSDN 上的文章
    在 Server 端存取 Excel 檔案的利器:NPOI Library

    坎尼這邊就不多話,直接進入今天主題

    II.範例

    首先開啟一個 Web 專案,把 NPOI 的 Library 加入專案中
    建立一個 Web page,在畫面上放入一個 Chart Control
    另外再放個 Gridview 來呈現資料 ,最後建立 Button 來觸發匯出的事件
    nwc01 將畫面切換到 .cs 檔裡
    引用這次範例中會用的兩個 Namespace:
    NPOI.HSSF.UserModel – 建立 Excel 內容
    NPOI.HSSF.Util - 建立相關樣式屬性

    nwc00 
    接著到匯出按鈕事件,建立 workbook 部分也跳過 (那不就什麼都沒講嗎? 毆
    nwc03上面的 Code 就不詳細說明,主要是將 Chart 存成 Stream
    再利用 NPOI 提供的圖片插入方法,把 Stream 轉為 Excel 可讀取的圖片格式
    (注意圖片的匯出格式以及匯入格式)
    最後再將整個 workbook 匯出即可 (見下圖)
    nwc02 資料部分坎尼本來還想加上樣式,後來覺得有點麻煩就作罷 (喂!

    III.結論

    NPOI 真的是很好用的 Library,建議有需求的人都可以去下載來試玩看看

    本次範例 下載

    參考資料:
    NPOI Codeplex
    在 Server 端存取 Excel 檔案的利器:NPOI Library
    用 NPOI 操作EXCEL--插入圖片

    Google Spreadsheet 裡用規則運算式

    最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D