2015年12月15日 星期二

[Linux] Screen

       撰寫程式時,經常會一邊執行(compile)程式碼,一邊繼續修改內容,有時還需要參考其他程式內容。因此,一次開個三四個執行視窗(putty/pietty)是很常見的事。但是使用這麼多個視窗,不僅切換相當不便,有時希望在螢幕上同時顯示數個視窗時,還需要花一些時間去調整式窗大小,相當不方便。在這種情況下,Screen就是一個相當好用的工具了。


       Screen 全名是Full-Screen Windows Manager,可以讓你在一個putty/pietty視窗下,同時開啟許多執行視窗,且視窗間的切換相當容易,也支援畫面分割(也就是可以在一個pietty視窗下,同時顯示兩個執行視窗)。這個有點像是Firefox或是chrome的分頁概念,但是使用上更方便。如此一來,就可以開一個執行視窗執行程式碼,然後再切換至第二個視窗撰寫程式碼,同時還能將畫面分割出第三個視窗,顯示想要參考的程式碼,再也不需花費額外的時間在切換pietty視窗,也不用擔心思路被打斷。


       除了能夠提供多視窗工作外,Screen更迷人的是允許離線背景作業,只要你離開時是使用detach離開,而不是exit,那麼在Screen模式下所開啟的所有視窗都可以被保留,若這些視窗中有正在執行的項目,也會在背景中繼續執行。對於經常在不同Project間來回穿梭的使用者來說,當Project A正在compile時,可以detach 當前的Screen,然後再開啟一個新的Screen處理Project B。除了背景執行功能可以省下等待的時間外,Screen還能保留在處理Project A時的環境,這樣再回頭處理Project A時,就能夠更快回憶起之前的進度。


     < Screen常用指令>
screen        :開啟screen功能,會直接跳到screen視窗中。
ctrl-a d        :detach screen,也就是暫時離開screen,screen會繼續再背景執行。
screen -r     : 喚醒被detach的screen。 -r 表示resume,如果只使用一個screen視窗,則直接用-r即可;若是已經開啟數個screen視窗的話,那後面就需要再加上screen 的ID。
screen -ls   :此指令會列出所有開啟的screen ID與該screen視窗是detached還是attached。
exit             :關閉當前的視窗,若只剩一個視窗,則離開screen。


       在screen中,所有操作都需伴隨Ctrl-a (C-a),如上述的ctrl-a d 就是指先同時按住ctrl 與 a鍵,放開後再按d鍵。下面這些都是screen模式中經常被使用的指令:


C-a c           :  開啟新的視窗,並同時移動至新開視窗。
C-a n或 C-a space                    :  切換至下一個視窗。
C-a p           :  切換至上一個視窗。
C-a C           :  清除當前視窗內容。


       除了上述這些常用熱鍵外,Screen 還有其他熱鍵,可以用C-a ? 查詢(或是直接man screen)。
雖然這些熱鍵並不複雜,但要一直按C-a還是有點麻煩,有時按太快還會讓電腦誤會(例如我之前習慣用C-a space來切換視窗,但有時按太快,反而變成切換輸入法了...),幸好,Screen有提供Bindkey(自訂熱鍵)的功能,只需要在安裝目錄下修改.screenrc即可。


       .screenrc的修改方式網路上有很多資源,而我主要是參考 [ 雅砌工坊 ] 所整理的配置,加上一些其他細部的調整,我覺得[ 雅砌工坊 ]  所提供的配置相當直接且方便,有興趣的歡迎自行前往參考。以下則是放上我所使用的配置(#號後面是註解):


# Start message (關掉screen的開啟訊息)
startup_message off
# Set hardstatus always on (在視窗底下新增狀態列)
hardstatus alwayslastline " %-Lw%{= Bw}%n%f %t%{-}%+Lw %=| %M %d %0c:%s "
(在狀態列中顯示系統日期與時間,Dec 15 13:33:21)此外,也有很多不同風格的狀態列可以使用,如


  • caption always "%{= wk} %{= KY} [%n]%t @ %H %{-} %= %{= KR} %l %{-} | %{= KG} %Y-%m-%d %{-} "
  • hardstatus alwayslastline " %-Lw%{= Bw}%n%f %t%{-}%+Lw %=| %0c:%s "
  • (除了顯示時間訊息外,也顯示load average的資訊)
  • caption always "%{=u .G} %-w%<%{=ub .y}%n %t%{=u .G}%+w "
  • hardstatus alwaysignore
  • hardstatus alwayslastline "%{= .K} [%l]%<%=%{= .W}@%H %=%{= .y} %Y/%m/%d%{= .m} %0c:%s "
  • (也是顯示時間與load average,只是配置風格不同)

# Set default encoding using utf8 ( 強制終端機編碼為utf8,這樣就可以看中文字了)
defutf8 on
# Refresh the display when exiting programs (離開視窗時重新整理螢幕)
altscreen ons
# Disable vbell (將操作熱鍵錯誤時的提示音關掉)
vbell off
# Scroll back (設定Scroll可以往上捲的行數)
defscrollback 10000


    <Keboard binding>
# bind F6 to list all screen windows (列出所有的screen 視窗)
bindkey -k k6 Windows
# bind F7 to detach screen session to background  (離開screen至背景,相當於C-a d)
bindkey -k k7 detach
# bind F8 to kill current screen window  (kill當前視窗,相當於exit)
bindkey -k k8 kill
# bind F9 to create a new screen (開新視窗,相當於C-a c)
bindkey -k k9 screen
# bind F10 to rename current screen window (重新命名當前視窗的標題)
bindkey -k k; title
# bind F11 to move to previous window (切換至前一個視窗,相當於C-a p)
bindkey -k F1 prev
# bind F12 to move to next window (切換至後一個視窗,相當於 C-a n)
bindkey -k F2 next
# bind ctrl-c to enter copy/scrollback mode  (切換至複製模式)
bindkey "^c" copy
# bind ctrl-v to paste the contents of the paste buffer (貼上複製範圍)
bindkey "^p" paste
       進入複製模式後,先使用方向鍵選取欲複製文字的開頭後,按下"空白鍵",此時會看到第一個字母已經反白。接著移動方向鍵選取欲複製的範圍,完成後按下大寫"Y",這樣screen就會將選取的內容存放到screen buffer,並且會在狀態列上顯示一共複製多少字母。 接著,便可利用ctrl-v 將暫存內容貼上。


      
       開頭時提到,Screen除了提供背景作業外或是多視窗工作外,也支援分割視窗。指令為:
ctrl-a S      :水平分割(上下)視窗,按幾次就分割幾個,分割後需要輸入欲顯示的視窗(例如利用F11、F12來選取)
ctrl-a Tab  :在不同的分割視窗間切換。
ctrl-a Q      :離開分割視窗。關閉所有的分割視窗,只留下目前focus的那一個。
ctrl-a X       :移除一個視窗。


同樣的,可以將分割視窗自訂熱鍵,並寫入.sceenrc中 ,如:
# bind alt-w to split the windows (水平分割視窗)
bindkey "^[w" split
# bind alt-v to vetically split the windows (垂直分割視窗)
bindkey "^[v" split -v
# bind alt-tab to switch to another split region (在不同分割視窗間切換)
bindkey "^[p" focus
# bind alt-q to quit delete all split regions but current focus one (關閉所有分割視窗,只留下當前focus的那個)
bindkey "^[q" only
(Note:  ^ 表示ctrl 鍵; ^[  表示 atl 鍵)


       此外, 由於screen中有許多預設的熱鍵,為避免不小心按到,網路上有一些建議remove調的指令,建議也可以放在.screenrc中,如:
# remove some default  key bindings
bind s   (避免不小心將螢幕鎖上)
bind k   (避免不小心kill視窗)
bind W
bind ^k
bind .
bind ^\
bind \\
bind ^h
bind h


<參考網站>






2015年11月17日 星期二

[NWP] 模式誤差_draft

模式誤差可以分為参數化誤差(或動力誤差)以及離散誤差。
前者主要來自於模式對真實大氣的描述能力不足,例如模式無法完整且正確地模擬出一朵積雲對流自生成到消散的過程,也無法完整表達積雲在對流過程中對環境的熱力與動力所造成的影響,這都會使數值模式在預報過程中產生誤差。
後者則是電腦計算過程中造成的誤差。由於數學上的微分方程都是連續的,若要在電腦上進行微分計算,必須將微分方程透過數值方法近似成差分方程,而在近似過程中會將高階項捨去;同時,電腦在計算時,受限於計算位數,也會將小數近似。這些數學方法近似過程中對模式造成的誤差稱作離散誤差。

2015年5月7日 星期四

[BashShell] 變數計算

Bash shell 的算術運算有四種方式。

1.  使用expr 
     ex: r=` expr 4 + 5 `
           r=` expr 4 \* 5 `

     note 1:  數字與符號間要有空白。
     note 2:  因為* 對於bash 來說有特殊意義(萬用字元),所以要先使用反斜線 (\) 來取消*的特殊意義。  
     note 3: expr無法使用(**)當作乘冪。
     note 4:expr 無法處理浮點運算,因此須改用其他方式,如$(())。
    
2.  使用 $(())
      ex: r=$(( 4 + 5))
            r=$(echo "4.0*2.0"|bc)  

       note 1:  此方式不需要使用反斜線來取消*的特殊意義。
       note 2:  亦可使用awk 來處理浮點運算,如:
           r=$(awk 'BEGIN{print 4.0*2.0 }')

            
3. 使用$[]
     ex: r=$[ 4 + 5 ]  

4. 使用let 
     ex: m=10
           let n=m+1
           則n=11
           (也可寫成let m=m+1 用來當作迴圈內計算)

NOTE:
 雖然上述四種方式都可以達到需求,但並非每個方式均可跨平台使用,建議使用expr會有較好的可攜性。