命名約定
1、函數名
使用小寫字母,並用下划線分隔單詞。使用雙冒號 :: 分隔庫。函數名之后必須有圓括號。關鍵詞 function 是可選的,但必須在一個項目中保持一致。
如果你正在寫單個函數,請用小寫字母來命名,並用下划線分隔單詞。如果你正在寫一個包,使用雙冒號 :: 來分隔包名。大括號必須和函數名位於同一行(就像在Google的其他語言一樣),並且函數名和圓括號之間沒有空格。
# Single function
my_func() {
...
}
# Part of a package
mypackage::my_func() {
...
}
當函數名后存在 () 時,關鍵詞 function是多余的。但是其促進了函數的快速辨識。
2、變量名
如函數名。
循環的變量名應該和循環的任何變量同樣命名。
for zone in ${zones}; do
something_with "${zone}"
done
3、常量和環境變量名
全部大寫,用下划線分隔,聲明在文件的頂部。
常量和任何導出到環境中的都應該大寫。
# Constant
readonly PATH_TO_FILES='/some/path'
# Both constant and environment
declare -xr ORACLE_SID='PROD'
第一次設置時有一些就變成了常量(例如,通過getopts)。因此,可以在getopts中或基於條件來設定常量,但之后應該立即設置其為只讀。值得注意的是,在函數中 declare 不會對全局變量進行操作。所以推薦使用 readonly 和 export 來代替。
VERBOSE='false'
while getopts 'v' flag; do
case "${flag}" in
v) VERBOSE='true' ;;
esac
done
readonly VERBOSE
4、源文件名
小寫,如果需要的話使用下划線分隔單詞。
這是為了和在Google中的其他代碼風格保持一致: maketemplate 或者 make_template ,而不是 make-template 。
5、只讀變量
使用 readonly 或者 declare -r 來確保變量只讀。
因為全局變量在shell中廣泛使用,所以在使用它們的過程中捕獲錯誤是很重要的。當你聲明了一個變量,希望其只讀,那么請明確指出。
zip_version="$(dpkg --status zip | grep Version: | cut -d ' ' -f 2)"
if [[ -z "${zip_version}" ]]; then
error_message
else
readonly zip_version
fi
6、使用本地變量
使用 local 聲明特定功能的變量。聲明和賦值應該在不同行。
使用 local 來聲明局部變量以確保其只在函數內部和子函數中可見。這避免了污染全局命名空間和不經意間設置可能具有函數之外重要性的變量。
當賦值的值由命令替換提供時,聲明和賦值必須分開。因為內建的 local 不會從命令替換中傳遞退出碼。
my_func2() {
local name="$1"
# Separate lines for declaration and assignment:
local my_var
my_var="$(my_func)" || return
# DO NOT do this: $? contains the exit code of 'local', not my_func
local my_var="$(my_func)"
[[ $? -eq 0 ]] || return
...
}
7、函數位置
將文件中所有的函數一起放在常量下面。不要在函數之間隱藏可執行代碼。
如果你有函數,請將他們一起放在文件頭部。只有includes, set 聲明和常量設置可能在函數聲明之前完成。不要在函數之間隱藏可執行代碼。如果那樣做,會使得代碼在調試時難以跟蹤並出現意想不到的討厭結果。
8、主函數main
對於包含至少一個其他函數的足夠長的腳本,需要稱為 main 的函數。
為了方便查找程序的開始,將主程序放入一個稱為 main 的函數,作為最下面的函數。這使其和代碼庫的其余部分保持一致性,同時允許你定義更多變量為局部變量(如果主代碼不是一個函數就不能這么做)。文件中最后的非注釋行應該是對 main 函數的調用。
main "$@"
顯然,對於僅僅是線性流的短腳本, main 是矯枉過正,因此是不需要的。
