Shell Script

bash function

bash有幾個概念

  • echo string
  • return exit status(a number, not a string)
  • share variable (可用bash -n filename檢查語法)

Shell

  • 帶參數的函數
    MSG=$1 # 代表shell的第1個參數
    foo() {
      msg=$1 # function的第一個參數
      echo "$msg"
    }
    
    呼叫方式:foo "hello"
  • 日期/時間
    # 格式化
    $(date +"%Y-%m-%d %H:%M:%S")
    # 設定
    date -s "20130122 02:02:03"
    # 轉換 (Linux)
    echo $(date +%F -d"1970-01-01 UTC 1372211942 seconds") => "2013-06-26"
    echo $(date +%s -d"20130622") => "1371830400"
    echo $(date +%s -d"20130622 09:01:02") => "1371862862"
    echo $(date +%F -d@1427385600) => "2015-03-27"
    
  • $(指令), $((運算式))
    ver=$(username -r)
    echo $ver
    
    結果:2618-128.e15
  • return value in function
    foo() {
      value=$1
      return "$value"
    }
    foo 456
    status=$?
    echo "status=$status"
    
    結果:status=456
  • 數字比較
    if [ "$status" -eq 456 ]; then
      ...
    else
      ...
    fi
    其中:
    -gt: >, greater than
    -ge: >=
    -lt: <, less than
    -le: <=
    -eq: ==
    -nq: !=
    
  • 字串比較
    # 大小比較
    if [[ "$s1" > "$s2" ]];
    if [[ "$s1" < "$s2" ]];
    if [[ "$s1" == "$s2" ]];
    # contains
    if [[ "$s1" == *"$s2"* ]];
    
  • Array (必須#!/bin/bash)
    # 走訪陣列
    arr=(John Mary Peter) 或 arr=("John" "Mary" "Peter")
    for x in ${arr[@]}; do
      echo "$x"
    done
    或
    for ((i=0; i<${#arr[@]}; i++)); do
      echo "$x"
    done
    
    # 給值
    arr=[]
    arr[0]=xxx
    arr[1]=yyy
    或
    arr=()
    arr+=(xxx)
    arr+=(yyy)
    
    # range
    for i in {1..5}; do
    done
    for i in {a..z}; do
    done
    
  • 讀檔
    cat file.txt | while read line; do
      echo "$line"
    done
    
    等效於
    while read line; do echo "$line"; done < file.txt
    
    ps: 此法因產生子shell process的關係,故有global/local變數問題
  • include
    source file.sh
    
  • md5

    md5sum file | awk '{print $1}'
    
  • 宣告整數

    declare -i x=100
    # 若0080則視為8進位
    # 10#0080才是10進位
    
  • return string
    get_ip() {
      echo "192.168.0.1"
    }
    ip="$(get_ip)"
    echo "$ip"
    
    結果:192.168.0.1
  • sed
    # 變更字串 (s: substitute)
    sed 's-\(username=\).*-\1welson-'
    
    代表由\(username=\).*\1welson \1代表第1個()內的保存字
    # 變更檔案內容 (參數: -i)
    sed -i 's/old/OLD/g' file.txt # g: global
    sed -i 's/old/OLD/2' file.txt # 2: 前2個
    sed -i 's/regex/d' file.txt # d: 刪某行
    
  • 讀取使用者輸入
    answer=""
    read -e -p "y/n?" answer # 將結果存於answer
    
  • 字串處理

    str="/tmp/"
    len=${#str} # 5
    substring=${str:1:3} # 由index=1取3位
    lastChar=${str:len-1:1} # 取最後一碼
    
    x=xyz.2.3.4.fc.i686
    y=${x#*fc} # .i686
    z=${y%.*} # 空值
    其中
    #: left strip
    %: right strip
    
    s="key:v1:v2:v3"
    echo "${s#*:}" # v1:v2:v3
    echo "${s%:*}" # key:v1:v2
    
    # 轉大小寫
    s="Hello"
    echo "${s^^}" # HELLO
    echo "${s,,}" # hello
    # for Mac
    echo $s | tr [:lower:][:upper]
    echo $s | tr [:upper:][:lower]
    
    # cut
    cut -c startIndex-stopIndex
    ## 應用在substring
    s="abcd/doclib/user.xml"
    echo $s | cut -c 1-8 => "abcd/doc"
    echo $s | cut -c 5- => "/doclib/user.xml"
    echo $s | cut -c 1- => 原字串
    ## 應用在smb.conf
    samba="x:123:a,b,c"
    echo $samba | cut -d':' -f2 => "123"
    echo $samba | cut -d':' -f3 => "a,b,c"
    
  • switch-case

    case "$var" in
      abc | xyz)
          echo "case 1 or 2"
          ;;
      ijk)
          echo "case 3"
          ;;
      *)
          echo "defaults"
          ;;
    esac
    
  • 印在同一行
    echo -ne "xxx\r"
    
  • 傳不定參數至script
    # A.sh
    array=$*
    for e in ${array[@]}; do
      echo $e
    done
    # 使用方式:
    A.sh 123 abc xyz
    
    應用:實作 ./script.sh --param1=v1 --param2=v2
    #!/bin/bash
    # 取出每一個參數
    params=$*
    for param in ${params[@]}; do
      echo "param=${param}, (k,v)=(${param%=*}, ${param#*=})"
    done
    #
    # 或
    #
    # 逐一比對每個參數
    while [ $# -gt 0 ]; do
      case "$1" in
          --param1=*)
              echo "param1 = ${1#*=}"
              ;;
          --param2=*)
              echo "param2 = ${1#*=}"
              ;;
          *)
              ;;
      esac
      shift
    done
    
  • 傳送json至shell script (要加單引號)

    # json字串須加單引號
    bash -x script.sh '[email protected]' '{"k1":"v1", "k2":"v2"}'
    # 若不加單引號,則{}須跳脫
    bash -x script.sh '[email protected]' \{"k1":"v1", "k2":"v2"\}
    
  • local variable

    str="global"
    foo() {
      local str="local"
      echo "$str"
    }
    foo
    echo "$str"
    

    結果

    local
    global
    
  • tput控制stdout的style

    echo "$(tput bold) ABC" # 粗體ABC
    echo "$(tput setaf i)" # 顏色: i={0(黑),1(紅),2(綠),3(黃),4(藍),5(Megenta),6(Cyan),7(白)}
    echo "$(tput sgr0) ABC" # reset
    echo "$(tput sgr 0 1)" # underline
    
  • Hash Table

    declare -A animals=(["k1"]="v1" ["k2"]="v2")
    echo v1=${animals["k1"]} # 印出v1
    echo keys=${!animals[@]} # 印出所有的keys. 可搭配 for key in ${!animals[@]}; do ... done
    
  • base64, big5
    # base64
    echo "abc" | base64 # YWJjCg==
    echo "YWJjCg==" | base64 -d
    # big5
    echo "abc" | iconv -f utf8 -t big5
    # binary
    echo "YWJjCg==" | xxd -b
    
  • 執行mysql指令
    /usr/bin/mysql -u username -p'password' -h $host <<EOFMYSQL
      create datebase if not exists $dbname;
    EOFMYSQL
    # 必須注意! 關鍵字`EOFMYSQL`不可縮排!
    
  • 查pid
    ps -ef | grep 'xxx' | grep -v grep | awk '{print $2}'
    

results matching ""

    No results matching ""