Bash Script Cheatsheet
被 bash 一堆特殊符號,還有語法格式衝昏頭了嗎?這篇文章會在幾分鐘內,快速介紹 bash script 的常用的一些特殊語法。
這不是 bash script 教學,也不是一分冗長的文件說明,這是 cheatsheet ,言簡意賅才是重點!
Built-in Variables
$0, $1, $2 # 第 n 個參數,即 argv[n]
$# # 參數數量,即 argc
$@ # 所有的參數
$? # 上一個指令的回傳值
$$ # 目前程式的 pid
$! # 上一個在背景執行的程式的 pid
$@
與$*
非常類似,他們的差別可以參考 stack overflow
Bash Builtins
- 數學運算,前兩個寫法等價
echo $((1+1))
echo $[1+1]
- 變數,
{}
可省略
name="John"
echo $name
echo ${name}
# 字串長度
echo ${#name} # 4
- 指令替換,兩個寫法等價
echo $(whoami)
echo `whoami`
- 展開
echo {1..5} // 1 2 3 4 5
echo {1..10..2} // 1 3 5 7 9
Logic Statement
- bash shortcut
echo hi && echo john # 前面成功執行的話,後面才會執行
grep 'notfound' /dev/null || echo 'Not found' # 前面指令失敗的話,後面才會執行
- if-else
字串用 ><=
一類的符號,數字則是用英文縮寫
if [ $age -ge 65 ] && [ $name == "John" ]; then
echo '...'
fi
Loop
- for each,這兩種 array 存取值的寫法是等價的
arr=(Alice Bob Oscar)
for i in {0..2}; do
echo ${arr[i]}
done
for i in "${arr[@]}"; do
echo $i
done
- C-style for loop
for (( i=1; i<=5; i++ )); do
echo $i
done
- while Loop
i=0
while [ $i -lt 5 ]; do
echo $i
((i++)) # 雙括號裡面可以寫 C-style 的運算式
done
Redirection
echo john | grep 'john' # pipe,第一個指令的 stdout 作為第二個指令的 stdin
echo hi > /tmp/text # stdout 輸出導向檔案並覆寫
echo hi >> /tmp/text # stdout 輸出導向檔案,附加在該檔案內容後
echo hi 2>&1 # stderr 導向 stdout
echo hi 1>&2 # stdout 導向 stderr
echo hi &> /tmp/text # stdout 與 stderr 都導向檔案
cat < /tmp/text # stdin 改從檔案讀入
cat <(echo hi) # 把括號中的輸出丟到 cat 指令當 stdin
Subshell (bash parallel script)
只寫 ()
的話 parent 會 wait subshell,這樣會失去平行的意義
(sleep 5)
echo done
加上 &
就可以讓 parent 不等 subshell,兩個 process 同時執行
(sleep 2; echo child) &
echo parent
Bash good practice
set -e # 只要遇到失敗的指令,就會立刻退出
set -x # 印出每個執行的指令
Reference: Johns Blog · Bash Cheat Sheet
其他什麼 function 之類的就不寫了。
我個人通常不會把 bash script 寫的太長,如果需要寫比較長的 script,我傾向用 Python3 + bash 來完成,不但結合 Python3 處理字串、數學運算、高可讀性的優點,也充分發揮 bash 指令的便捷性。
如果真的要精通 bash ,可以讀一下 Advanced Bash-Scripting Guide,小心不要走火入魔……
後記
本來以為我可以算是「會寫」 bash script、script language 的人,但我 2017 年上旬去 Yahoo summer intern interview 的時候,面試官就問了我一些題目,例如$@
、$*
的差別, 還有 set -ex
跟 find
, xargs
的一些用法,我幾乎都答不出來。
很明顯我看別人的 script ,加上自己寫的 script 都不夠多,現階段充其量也只能算是「略懂略懂」吧。
你熟悉 Linux 作業系統嗎?我看就連 Linux Torvald 對當今的 kernel - Linux 4.10,恐怕也會謙虛的說道他「略懂」 Linux 系統吧!