Skip to main content

· 3 min read

本篇文章是用來記錄以前修課關於 Shell Script 的作業

Introduction

用Unix的指令,透過pipe的方式完成下列要求

  • 計算當前目錄底下資料夾的總數
  • 計算當前目錄底下檔案總數
    • 只有計算regular file.不考慮FIFO、LINK
  • 計算所有檔案大小和 (Byte)
  • 顯示前五大的檔案名稱
  • 只能使用PIPE,不能使用 $$ ; || & > >> <

Implement

  • 使用ls來取得所有資料夾跟檔案的資訊
    • -l 可以顯示詳細資訊,這邊我們要取得的是 檔案大小
    • -R 遞迴的往每個資料夾繼續往下找
    • -A 不要把...給顯示出來,因為這種當前目錄的東西我們不需要
  • 使用sort來幫忙排序,找出檔案大小前五個
    • -r 排序結果反過來,由大到小排序
    • -n 排序的時候,採用數字的方式去排序,不使用字母大小去排序
    • -k 指定第幾個欄位要排序
  • 使用awk作最後的處理,找出前五大,印出所有檔案大小和
    • 因為再ls -l的結果中,會有很多資訊,包含 ./cs/.svn/pristine/74: 或者 total 28,所以awk再處理的時候,先用NF判斷該行的欄位數,至少要有9個欄位才處理 if(NF>=9)
    • 接下來針對檔案是資料夾還是檔案,做全部的計數,可以由 -rw-r--r-- 的第一個欄位來決定,如果是d就代表資料夾,否則就是檔案。 這邊我使用 regular expression來判斷 ($1 ~/^d/)? (dir=dir+1) : (file=file+1)(size=size+$5),此外如果是檔案得話,就順便把大小也計算一下
    • 執行過程中,因為剛剛已經排序過了,所以 前六行都把大小印出來, if(NR<6) print NR": "$5" "$9}
    • 最後就把所有資訊都列印出來

ls -RlA | sort -rnk 5 | awk '{ if(NF>=9) ($1 ~/^d/)? (dir=dir+1) : (file=file+1)(size=size+$5); if(NR<6) print NR": "$5" "$9} END{ print "Dir = "dir"\n" " File = " file"\n" "total = "size}'

· 4 min read

之前機器因為ZFS空間滿了,因為平常有再作snapshot的緣故,導致東西都刪除不了 因為刪除的時候都會有一些metadata的寫入,導致整個zfs動彈不得,這時候就花了很多時間再研就怎麼處理 這邊稍微記錄一下ZFS相關得操作。 ZPOOL的來源可以是device也可以是files,這邊就用兩個檔案當作來源。

Files

  • sudo dd if=/dev/zero of=/zfs1 bs=1M count=256
  • sudo dd if=/dev/zero of=/zfs2 bs=1M count=256

Zpool

  • create a mirror pool
    • zpool create ftphome mirror /zfs1 /zfs2
  • destroy a pool
    • zpool destroy ftphome
  • check zpool status
    • zpool status <pool>
  • export pool ( 把某些pool export出去,暫時不使用)
    • zpool export ftphome
  • import pool ( 把被export 的pool 重新import回來)
    • zpool import -d / ftphome (用-d指定你檔案的位置,預設會去吃/dev/)
    • 以我的範例來說,當import回來後,名稱會變成 //zfs1, //zfs2,多了一個/,原因不明中。
  • attach ( 只能對mirror使用)
    • zpool attach ftphome /xxx
  • detach ( 只能對mirror使用)
    • zpool detach ftphome /zfs1

還有offline,online,remove...,剩下的就要用的時候去man zpool,還滿詳細說明的。

ZFS database

  • set attributes zfs set key=value <filesystem|volume|snapshot>
    • zfs get compression ftphome
    • zfs set mountpoint=/home/ftp ftphome
  • get attributes zfs get key <filesystem|volume|snapshot>
    • zfs get compression ftphome
  • snapshot
    • zfs snapshot ftphome@today
    • zfs list -t snapshot

其他

  • 假如你的ZFS有使用snapshot同時空間又滿的話,這時候會發現所有檔案都會刪除失敗,都會得到空間不足的訊息,這邊稍微模擬一下該情況,並且想辦法解決此問題。

模擬情況

snatshot 該zfs

  • zfs snapshot ftphome@today
  • zfs list -t snapshot 看一下是否有成功

塞爆該空間

  • zfs list 看一下還剩下多少空間
  • dd if=/dev/random of=/home/ftp/file bs=1M count=256
  • cd /home/ftp
  • rm file => 應該會得到 No space left on device空間不足的訊息。

解決問題

ZFS 變大容易(多塞個硬碟即可),變小困難(幾乎無法),因此當ZFS的硬碟滿的時候,有兩種做法

  1. 再加入兩個新的硬碟,然後合併到目前的zpool,可是這樣就會變成有兩份mirror。
  2. 準備兩個更大的硬碟,把原本的zpool內的data全都複製過去。 這邊使用第二種做法

先幫本來的pool加入一個檔案,增加本來的空間,如此一來才可以做更多操作

  • dd if=/dev/zero of=/zfs5 bs=1M count=128
  • dd if=/dev/zero of=/zfs6 bs=1M count=128
  • zpool add ftphome mirror /zfs5 /zfs6
  • zfs list (此時可以看到本來的空間變大了)

創造一個更大的zpool來取代

  • dd if=/dev/zero of=/zfs3 bs=1M count=512
  • dd if=/dev/zero of=/zfs4 bs=1M count=512
  • zpool create ftphome3 mirror /zfs3 /zfs4
  • zfs set compression=gzip-9 ftphome2

把資料複製過去

  • zfs snapshot ftphome@send
  • zfs send ftphome@send | zfs receive -F ftphome2
  • zfs list 看一下大小是否相同

mount新的,舊的砍掉

  • zfs umount ftphome
  • zfs set mountpoint=/home/ftp/ ftphome2
  • zpool destroy ftphome

做到這邊,就算完成了,成功的把本來的資料複製過去。 如果想要改變zpool的名稱,可以用exportimport來改名稱。

· 3 min read

最近重新整理vim的設定檔,意外的發現 http://yoursachet.com/ 這個網站滿好用的,可以根據你的需求來自動打造vim設定檔,對於不想動腦去研究設定檔而言的人來說是滿好用的工具 用滑鼠輕鬆點點就可以產生堪用的VIM了!!

vimrc 設定

set encoding=utf-8
set fileencodings=ucs-bom,utf-8,big5,latin1
set fileencoding=utf-8
set termencoding=utf-8
set number " 行號
set statusline=%<\ %n:%f\ %m%r%y%=%-35.(line:\ %l\ of\ %L,\ col:\ %c%V\ (%P)%)
set ai " 自動縮排
syntax on " 色彩標示

set tabstop=4 " tab使用四個空白取代
set shiftwidth=4 " 縮排空白數,要搭配set cin使用
set cin
set cursorline " 該行的線
set t_Co=256 " 支援 256 色
set textwidth=0
set backspace=2 "按下backspace會後退,道行首後會刪除到前一行
set showmatch "顯示括號配對情況
set nocompatible "用vim的特性去運行,捨棄vi的特性

" Pathogen
call pathogen#infect()
call pathogen#helptags()

filetype plugin indent on

" Nerdtree
autocmd VimEnter * NERDTree
autocmd VimEnter * wincmd p
let NERDTreeShowBookmarks=1
let NERDTreeChDirMode=0
let NERDTreeQuitOnOpen=0
let NERDTreeMouseMode=2
let NERDTreeShowHidden=1
let NERDTreeIgnore=['\.pyc','\~$','\.swo$','\.swp$','\.git','\.hg','\.svn','\.bzr']
let NERDTreeKeepTreeInNewTab=1
let g:nerdtree_tabs_open_on_gui_startup=0


set background=dark "背景顏色
colorscheme wombat
nnoremap <silent> <F5> :NERDTree<CR>
"normal mode的時候+數字 可以切換tab
nnoremap <Esc>1 gt1
nnoremap <Esc>2 gt2
nnoremap <Esc>3 gt3
nnoremap <Esc>4 gt4
nnoremap <Esc>5 gt5
nnoremap <Esc>6 gt6
nnoremap <Esc>7 gt7
nnoremap <Esc>8 gt8

NERDTree

更改呼叫方式,使用F5

nnoremap <silent> <F5> :NERDTree<CR>

在各界面中移動

  • 按照順序往下移動 (crtl+w+w)
  • 上一個view (ctrl+w+h)
  • 下一個view (ctrl+w+l)

切割視窗

  • 水平切割 (在該檔案前按i)
  • 垂直切割 (在該檔案前按s) i :水平 s :垂直

tab使用

  • 開新tab並且切換過去 (t)
  • 開新tab但不切換過去 (T)
  • 下一個tab (gt)
  • 上一個tab (gT)

· 2 min read

Introducion

Cscope 是一個用來trace code還滿方便的工具 我通常都用他來trace linuxe kernel code,雖然說有網頁版的reference可以使用,但是用起來不順手,網頁會卡卡的 因此還是習慣使用這種互動式的trace tools

Install

sudo apt-get install cscope on Ubuntu

portmaster devel/cscope on FreeBSd

Usage

詳細的可以參考man page. 通常我只有使用 -R 來觀看而已

第一次執行的時候,會花比較久的時間去建立一個cscope.out的檔案,會把一些相關資訊放進去

下次執行的時候就會利用該out檔案來作查詢。

其他

預設的情況下,cscope只能讀取

  • .c
  • .h
  • .l
  • .y

想要讓他讀取java或是cpp的專案,就必須要先自己建置該資料庫

  • find ./ -name *.cpp > cscope.files
  • fine ./ -name *.java >> cscope.files
  • cscope -bkq

前面兩行會把所有的檔案路徑都寫入倒cscope.files裡面

  • b:建立索引文件
  • k:建立索引文件時不會去搜尋/usr/local/目錄
  • q:生成cscope.out,加速索引,該檔案包含
    • locate functions
    • function calls
    • macros
    • variables
    • preprocessor symbols

接下來只要使用cscope就可以了

· One min read

文章轉移

  • rsync cycbuff
  • rsync db/history
  • 重新建立overview
    • ctlinnd pause 'make overview'
    • makehistory -x -O -b x: won't write out history file entries. O: Create the overview database b: Delete any messages found in the spool that do not have valid Message-ID: headers in them.
    • makedbz -i i:To ignore the old database
    • ctlinnd go 'over'

設定檔檢查

  1. inncheck (inn.conf)
  2. scanspool -v (active, spool)

更新相關設定

  • 重新編譯innd,進入innd src底下
  • ./configure --opetions
  • make && make update

創新的newsgroup

  • ctlinnd newgroup name
  • modity db/newsgroup

其他

  1. 創新newsgorup
  1. 執行innd & nnrpd 會噴權限不足
    • 檢查/news/bin/innbind 有無SUID

· 2 min read

Install

直接透過atp-get 安裝即可

sudo apt-get install sphinx

Config

安裝完畢後,執行

sphinx-quickstart就可以基本設定了

每個選項都有說明,基本上都採用預設值即可

  • 設定檔: conf.py

    • 外掛管理
    • 資料夾結構管理
    • 一些通用參數,如作者名稱,版本...等
  • 主要的檔案: index.rst -. 檔案的結構 -. toctree

index.rsta

Lab Meetgins
=============
.. toctree::
:maxdepth: 4
:titlesonly:

20130924.rst
20131001.rst

國科會 meetings
===============
.. toctree::
:maxdepth: 4
:titlesonly:

20130925.rst

這邊我定義兩個toctree,每個toctree底下又會有其他的rst,結構大概是這樣

  • Lab Meetings
    • 20130924.rst
    • 20131001.rst
  • 國科會 meetings
    • 20130925.rst

總共兩個分類,每個分類底下的文章都是一個額外的rst檔案

在toctree底下的都是一些設定參數

  • maxdepth : 最大深度
  • titlesonly : 在首頁面只顯示子類的標題

Write

Sphinx採用的reStructuredText 格式跟markdown很類似,但是複雜了一些 官方網站有滿詳細的介紹,有需要時再去參考即可

Build

如果想要轉成html網頁,有兩種方法可以執行

  1. sphinx-build -b html . NSLMeeting 意思是建置html的網頁, 然後以當前目錄為source 來源,然後把檔案build到NSLMetting去。

  2. make html 在Makefile中定義了相關得動作,當執行make html的時候,其實就是執行 sphinx-build -b html . _build/html

這邊因為我想要直接弄到別的資料夾,所以我直接設定aliase去執行方法1

目前對於這套軟體還在學習階段,有任何學習會繼續紀錄。

· One min read

記錄一下執行floodlight時,有ㄧ些參數可以使用,都是用來指定設定檔的位置。

Floodlight configuraion:

--configFile ${configuration path}

Log configuraion:

-Dlogback.configurationFile=${FL_LOGBACK}

範例

java -Dlogback.configurationFile=logback.xml floodlight.jar --configFile floodlightdefault.properties

· 3 min read

pack & unpack

根據特定的格式來讀取或封裝資料。

格式部份分成兩個部份

byte-order: 這邊可以決定採用big-endian 或是 little endian, 如果沒有給的話,預設是採用系統的方式去做,那這邊比較要注意到的是 以前再寫C語言的時候,都會有所謂的htons...類的轉換,在這邊可以使用'!' 這個符號來解決這個問題,他會自己使用network的Byte order rule去解讀資料,所以有在用網路連線傳資料的話,一定要用! 避免資料解讀錯誤的問題。

format-characters:

常用的有

  • x:pad byte,就忽略他
  • h:short,2 Byte
  • s:char[], 代表字串,使用時前面要加上數字
  • i:long int, 4Byte
  • B:unsigned char, 1 Byte

詳細的格式資訊請參考官網 Python struct

這邊來個簡單範例 假設今天我們撰寫屬於自己的網路遊戲 然後我們玩家每次上線時,SERVER都會傳送一份玩家的資料給Client

這份資料包含了

  • 遊戲版本
  • 玩家ID
  • 玩家的座標(XY)
  • 玩家當前的財產
  • 玩家的職業
  • 玩家的等級
  • 玩家的經驗值

每個資料所需要的型態跟大小如下敘述

Myheader(){
uint8:version
uint8:playerID
uint16:x
uint16:y
uint32:momey
char10:profession
uint8:level
uint32:experience
}

所以傳送資料過來的時候,我們必須要謹慎的按照這個規格去放置我們的資料。

Example

假設

  • version = 1
  • playerID = 56
  • x = 123
  • y = 2341
  • momey = 5566217
  • profession = "warrior"
  • level = 128
  • experience = 2147383611
data = pack('2B2HI10sBI',version,playerID,x,y,momey,profession,level,experience)
//'\x018{\x00%\t\x00\x00\t\xefT\x00warrior\x00\x00\x00\x80\x00\xdb\xff\xff\x7f'
unpack('2B2HI10sBI',data)
(1, 56, 123, 2341, 5566217, 'warrior\x00\x00\x00', 128, 2147483611)

· 2 min read

nmap是一個linux下的工具

nmap - Network exploration tool and security / port scanner

這邊記錄一下nmap的用法

nmap -sP 140.113.214.79/27

-sP: Ping Scan - go no further than determining if host is online 用ping去掃目標內的所有IP,並顯示有回應的IP,所以若對方是windows7且沒有打開ping的回應,則也會被當作host down

nmap -sL 140.113.214.79/27

-sL: List Scan - simply list targets to scan 只是單純的列出對方的hostname以及IP,不送出任何封包去檢測

nmap -O 140.113.214.94 nmap -A 140.113.214.94

-O: Enable OS detection -A: Enables OS detection and Version detection, Script scanning and Traceroute

掃描對方主機的OS系統

nmap -PS/PA/PU/PY[portlist] 140.113.214.94

-PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports

用不同的方式去掃描特定的PORT。

  • PS 用TCP 搭配 SYN FLAG去偵測。
  • PA 用TCP 搭配 ACK FLAG去偵測。
  • PU 用UDP去偵測。
  • PY 用SCTP去偵測。

nmap -sS/sT/sU 140.113.214.94

採用不同的方式去掃描所有port。

  • sS (TCP SYN scan) .
  • sT (TCP connect scan)
  • sU (UDP)

nmap -v 140.113.214.94 顯示出詳細一點的資訊

· 3 min read

Python中有個很強大的字串轉換工具 maketrans 跟 translate

str.translate(table[, deletechars]);
Parameters
table -- You can use the maketrans() helper function in the string module to create a translation table.

deletechars -- The list of characters to be removed from the source string.

字串中只要有符合deletechars中的字元都會被刪除,然後剩下的字元就會依照table裡面的mapping來做轉換。

這個mapping的就要利用string.maketrans()來幫忙產生囉,

str.maketrans(intab, outtab]);
Parameters
intab -- This is the string having actual characters.

outtab -- This is the string having corresponding mapping character.

intab跟outtab兩者的長度必須要一樣,會把intab中每一個字元與outtab中相同位置的字元做mapping。

舉例來說

    intab = "aeiou"
outtab = "12345"
trantab = maketrans(intab, outtab)

就會產生一個mapping,把aeiou分別轉換成12345。

    input="abcdefgh"
input = input.translate(trantab)

input就會變成 "1bcd2fgh"

那如果改成

    input="abcdefgh"
input = input.translate(trantab,"fgh")

input就會變成 "1bcd2"

再來個簡單範例,希望能夠把所有的小寫轉成大寫,並把非英文字母外的所有字元都給刪除掉。

import string

#取得所有英文大小寫的集合

    lower = ''.join(map(chr,range(97,123)))
upper = lower.upper()

#創立一個對照表,可以把所有小寫轉成大寫

    ltu = string.maketrans(lower,upper)

#接下來要利用捕集的方式取得非英文字母以外的所有字元,因此就用所有字元-英文字母 #創立一個代表所有字元的字元表

    allchars = string.maketrans('','')

#利用translate的方式,取得所有非英文字母的集合

    delete = allchars.translate(allchars,lower+upper)

#定義一個對應的function,傳入的字串利用ltu跟delete,就能夠把所有非英文字母都刪除,並且小寫轉大寫了。

    def makefilter(input):
print input.translate(ltu,delete)