我的所有bash指令碼都以下面幾句為開場白:
#!/bin/bash
set -o nounset
set -o errexit
這樣做會避免兩種常見的問題:
引用未定義的變數(預設值為「」)
執行失敗的命令被忽略
需要注意的是,有些linux命令的某些引數可以強制忽略發生的錯誤,例如「mkdir -p」 和 「rm -f」。
在bash裡你可以定義函式,它們就跟其它命令一樣,可以隨意的使用;它們能讓你的指令碼更具可讀性:
extractbashcomments()
cat myscript.sh | extractbashcomments | wc
comments=$(extractbashcomments < myscript.sh)
還有一些例子:
sumlines() + $))
done
echo $
} sumlines < data_one_number_per_line.txt
log() $@" >&2
} log "info" "a message"
盡可能的把你的bash**移入到函式裡,僅把全域性變數、常量和對「main」呼叫的語句放在最外層。
bash裡可以對變數進行有限的註解。最重要的兩個註解是:
local(函式內部變數)
readonly(唯讀變數)
# a useful idiom: default_val can be overwritten
# with an environment variable of the same name
readonly default_val=$
myfunc()
...}
這樣,你可以將乙個以前不是唯讀變數的變數宣告成唯讀變數:
x=5
x=6readonly x
x=7 # failure
盡量對你bash指令碼裡的所有變數使用local
或readonly
進行註解。
反單引號很難看,在有些字型裡跟正單引號很相似。$()
能夠內嵌使用,而且避免了轉義符的麻煩。
# both commands below print out: a-b-c-d
echo "a-`echo b-\`echo c-\\\`echo d\\\`\``"
echo "a-$(echo b-$(echo c-$(echo d)))"
使用
能避免像異常的副檔名之類的問題,而且能帶來很多語法上的改進,而且還增加了很多新功能:
操作符 功能說明
|| 邏輯or(僅雙中括號裡使用)
&& 邏輯and(僅雙中括號裡使用)
< 字串比較(雙中括號裡不需要轉移)
-lt 數字比較
= 字串相等
== 以globbing方式進行字串比較(僅雙中括號裡使用,參考下文)
=~ 用正規表示式進行字串比較(僅雙中括號裡使用,參考下文)
-n 非空字串
-z 空字串
-eq 數字相等
-ne 數字不等
[ "$" \> "a" -o $ \< "m" ]
[[ "$" > "a" && "$" < "m" ]]
使用雙中括號帶來的好處用下面幾個例子最能表現:
t="abc123"
[[ "$t" == abc* ]] # true (globbing比較)
[[ "$t" == "abc*" ]] # false (字面比較)
[[ "$t" =~ [abc]+[123]+ ]] # true (正規表示式比較)
[[ "$t" =~ "abc*" ]] # false (字面比較)
注意,從bash 3.2版開始,正規表示式和globbing表示式都不能用引號包裹。如果你的表示式裡有空格,你可以把它儲存到乙個變數裡:
r="a b+"
[[ "a bbb" =~ $r ]] # true
按globbing方式的字串比較也可以用到case
語句中:
case $t in
abc*) ;;
esac
bash裡有各種各樣操作字串的方式,很多都是不可取的。
基本使用者
f="path1/path2/file.ext"
len="$" # = 20 (字串長度)
# 切片操作: $ or $
slice1="$" # = "path2/file.ext"
slice2="$" # = "path2"
slice3="$" # = "file.ext"(注意:"-"前有空格)
pos=6
len=5
slice4="$:$}" # = "path2"
替換操作(使用globbing)f="path1/path2/file.ext"
single_subst="$" # = "x/path2/file.ext"
global_subst="$" # = "x/x/file.ext"
# 字串拆分
readonly dir_sep="/"
array=($/ })
second_dir="$" # = path2
刪除頭部或尾部(使用globbing)f="path1/path2/file.ext"
# 刪除字串頭部
extension="$" # = "ext"
# 以貪婪匹配方式刪除字串頭部
filename="$" # = "file.ext"
# 刪除字串尾部
dirname="$" # = "path1/path2"
# 以貪婪匹配方式刪除字串尾部
root="$" # = "path1"
有些命令需要以檔名為引數,這樣一來就不能使用管道。這個時候就顯出用處了,它可以接受乙個命令,並把它轉換成可以當成檔名之類的什麼東西:
diff
還有乙個非常有用處的是」here documents」,它能讓你在標準輸入上輸入多行字串。下面的』marker』可以替換成任何字詞。
# 任何字詞都可以當作分界符
command << marker
...$
$(cmd)
...marker
如果文字裡沒有內嵌變數替換操作,你可以把第乙個marker用單引號包起來:
command << 'marker'
...$ (dollar sign) is passed through verbatim.
...marker
變數 說明
$0 指令碼名稱
$n 傳給指令碼/函式的第n個引數
$$ 指令碼的pid
$! 上乙個被執行的命令的pid(後台執行的程序)
$? 上乙個命令的退出狀態(管道命令使用$)
$# 傳遞給指令碼/函式的引數個數
$@ 傳遞給指令碼/函式的所有引數(識別每個引數)
$* 傳遞給指令碼/函式的所有引數(把所有引數當成乙個字串)
提示
使用\(*很少是正確的選擇。
\)@能夠處理空格引數,而且引數間的空格也能正確的處理。
使用\(@時應該用雙引號括起來,像」\)@」這樣。
對指令碼進行語法檢查:
bash -n myscript.sh
跟蹤指令碼裡每個命令的執行:
bash -v myscripts.sh
跟蹤指令碼裡每個命令的執行並附加擴充資訊:
bash -x myscript.sh
你可以在指令碼頭部使用set -o verbose
和set -o xtrace
來永久指定-v
和-o
。當在遠端機器上執行指令碼時,這樣做非常有用,用它來輸出遠端資訊。
這個時候,你應該考慮一種指令碼語言,比如python或ruby。
15分鐘了解Phoenix
以下部分翻譯自 phoenix為hbase穿上一層sql的外衣。所以你可以使用標準的jdbc api來建立表 插入資料 查詢hbase中的資料,而不是使用常規的hbase客戶端api。不會。跟原生的hbase客戶端相比,phoenix效能一樣好甚至更好,主要通過以下方式 除此之外,我們還做了一些工作...
15分鐘了解TiDB
2019年07月13日 22 21 49 d guco 閱讀數 77341 由於目前的專案把mysql換成了tidb,所以特意來了解下tidb。其實也不能說換,由於tidb和mysql幾乎完全相容,所以我們的程式沒有任何改動就完成了資料庫從mysql到tidb的轉換,tidb 是乙個分布式 news...
Git五分鐘教程
使用git前,需要先建立乙個倉庫 repository 您可以使用乙個已經存在的目錄作為git倉庫或建立乙個空目錄。git initgit init newrepo從現在開始,我們將假設您在git倉庫根目錄下,除非另有說明。我們有乙個倉庫,但什麼也沒有,可以使用add命令新增檔案。git add f...