over 5 years ago

本文為使用linux shell script的心得,詳細的指令介紹建議參考鳥哥的 Linux 私房菜或利用搜尋頁搜尋指令。

  • shell script 的註解為 # 開頭,在 # 之後的任何字元都會被忽略。
  • 變數命名必須與=連在一起:

    #錯誤寫法
    
    start = 20091104
    #正確寫法
    
    start=20091104
    

    變數給值時直接寫變數名稱,但若是其他指令要用到時則要加$或是${},以上述範例為例則是$start${start}

  • 異動執行環境的編碼

    # 將執行環境的編碼改成 Big5
    
    export LANG=zh_TW.Big5
    # 將執行環境的編碼改成 UTF8
    
    export LANG=en_US.UTF-8
    
  • shell也是可以寫function來重複執行一連串的command:

    testFunction() {
    #echo第一,第二個參數值
    
    echo $1 $2
    }
    testFunction test1 test2
    
  • for 迴圈

    for (( i=1; i<=9; i++ ))
    do
    ${JAVA_HOME}/bin/java -Xms256m -Xmx1024m -cp .:test.jar:ojdbc14_2.zip com.xxx.xxx 2013070$i
    done
    
  • 使用array

    #宣告filelist為一陣列
    
    declare -a filelist
    filelist=(`ls -l|awk '{print $9}'`)
    #陣列的索引從 0 開始,ex:${list[0]}
    
    #列出陣列的個數
    
    echo count=${#filelist[*]}
    #依序列出每一個檔案或資料夾名稱
    
    for i in ${filelist[*]}
    do
        echo $i
    done
    
  • if 判斷式

    • = 判斷字串或數值是否相等。
    • -e 判斷檔案是否存在。
    • -ne判斷檔案是否不存在或二邊數值不相等。
    • -gt 判斷數值是否大於後面的值。
    • -ge 是否大於等於後面的值。
    • -lt 是否小於後面的值。
    • -le 是否小於等於後面的值。
    • 二項以上判斷絛件,二項條件皆成立用 &&-a ,二項條件一項以上成立用 ||-o
if [ "$1" = "" ]; then
  echo "please input server IP"
  exit
fi

若未輸入參數則出現please input server IP提示字串並離開此程式。

if [ -e ${tarHour}.tar.gz ]; then  
    tar xvfz ${tarHour}.tar.gz
else
  echo "${tarHour}.tar.gz not exist"
fi

若${tar.Hour}.tar.gz檔案存在則解壓縮,反之則顯示not exist。
若要判斷不存在可寫成 if [ ! -e ${tarHour}.tar.gz ]; then 或是 if [ -ne ${tarHour}.tar.gz ]; then

if [ "$errCount" -gt 3 ]; then
    echo "error"
fi

若errCount數值超過3,顯示error。

if [ "$1" -ne "" -a "$1" -gt 1 ]; then
  echo "ok"
fi

if [ "$1" -ne "" ] && [ "$1" -gt 1 ]; then
    echo "ok"
fi

上述二件 if 判斷式都是判斷input的第一個參數是否非空值且大於1,是的話則印出 ok。


awk

根據輸入的每一行資料,以空格切成多個欄位來處理。

#列出當前目錄下所有的資料夾及檔案名稱

ls -l|awk '{print $9}'

awk切割欄位起始值為1,若要改以,為切割點則改成awk -F, '{print $9}'

cat

列出檔案內容

cat test.txt

more不同的是cat會全部列出,more則是一次只列出一個畫面能顯示的內容。

crontab

每隔一段時間執行指定的command。一行一個指令,變數依序為
minute hour date month week command

#每天 7:10 執行 test.sh 這隻程式

10 7 * * * sh /home/user/test.sh

crontab的sh output最好要輸出,否則若print出來的字數過多,跑到一半有可能會中斷掉!
若不需記錄output結果,則新增> /dev/null 2>&1即可。
其中第一個output > 是standard output,像是Java的System.out.print();就是由此輸出。
第二個output 2> 則是error output,Java的System.err.print();及exception都是輸出在此。
以下則是加上output的crontab範例:

#每天 7:10 執行 test.sh 這隻程式

10 7 * * * sh /home/user/test.sh >/dev/null 2>&1

date

顯示日期、時間,顯示參數有:
%Y 年,ex:2013
%m 月,ex:07
%d 日,ex:24
%H 時,ex:21
%M 分,ex:05
%S 秒,ex:31

# 20130724

today=`date -d "0 days ago" +%Y%m%d`
# 20130723

yesterday=`date -d "1 days ago" + %Y%m%d`

expr

#將變數 i 的值加1

i=`expr $1 + 1`

在四則運算(+ - * /)的二邊都要有空白,否則會有error。
若要使用乘號*,需寫成 \*

find

#搜尋目前目錄下(含子目錄)所有 .sh 檔案

find ./ -name '*.sh'

ftp

ftp -n << END
open ${serverIP}
user username password
bin
prom
cd test/log/
get ${tarHour}.tar.gz
close
bye
END

END為結束字串,可自行定義,如改成 STOP, OVER ... 等,只需注意頭尾字串要相符合即可。
open要連線的server
user要登入的ftp帳號、密碼
bin設定要處理的檔案是binary而非ascii文字檔。
prom當檔案已存在時,不詢問'y'或'n',直接覆蓋。
get下載檔案,上傳用put
close結束下載檔案。
bye結束連線。
ftp 到結束字串間的指令,不可縮排(每一行開頭有空白或tab)。

ntpdate

#透過crontab每天1:15向 switch 同步更新時間

15 1 * * * /usr/sbin/ntpdate -s 172.30.1.254; /sbin/hwclock -w

sed

#取代字串

sed 's/要被取代的字串/新的字串/g'

#將file中的第n行到第m行的文字輸出到output.txt

cat file|sed -n 'n,mp' > output.txt

sort , uniq

#以列為單位,排序後濾掉重複部份,並輸出到result.txt此檔案

cat test.txt|sort|uniq > result.txt

split

#切檔 -l 每多少行切成一個檔案 原始檔 新檔名的prefix

split -l 100 test.txt newTest

會將 test.txt 切成100行一個檔案,檔名分別為newTestaa,newTestab,newTestac ...

stat

#取得 file.log size

stat -c %s file.log

tr

#刪除特定字元

tr -d '\r' > output

#將a.txt的所有小寫字元換成大寫字元並輸出到b.txt

tr '[a-z]' '[A-Z]' < a.txt > b.txt

wc

#取得a.txt檔案的行數

wc -l a.txt
← 使用 Git + Dropbox + SourceTree 做 Source Code Management