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
ps: 此法因產生子shell process的關係,故有global/local變數問題while read line; do echo "$line"; done < file.txt
- 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}'