本文主要講bash指令碼中容易出錯和很少用但是用起來有意想不到效果的部分。
正常的for迴圈:
for i ina b c 1 2 3; do
echo"$i
"done
數字序列迴圈:
for i in `seq100`; do
echo"$i
"done
其中的 `seq
100` 也可以換成
的這種形式可以表示連續的數列,可以從小到大也可以從大到小,但是可惜不像python的range()那樣可以指定間隔量
c語言風格的for迴圈:
for (( i=1; i<100; i++ )); doecho"$i
"done
for迴圈會使用空格、換行符、製表符分割文字,依次迭代,如:
a="ab cd
ef"for i in
$a;
doecho
"$i"
done
輸出結果:
abcdef
shell分割文字其實是以乙個全域性變數$ifs為依據的,預設情況下ifs=$'\n\t '(即換行符、製表符、空格),可以通過修改ifs的值來改變迭代文字的分割方式。
請注意上面的$a如果加引號括起來的話,會把它當成乙個整體,不會切割迭代。
雙括號「(())」還可以用於數學計算:
(( a=123+456))echo$a#
579
在雙括號中,變數並不需要用$符號來引用,英文單詞天然是變數。
a=bb=100
echo $
#100
效果等同於 eval echo \$$a
包含特殊字元的字串:
echo"ab\ncd
"
上列命令會輸出字元ab+換行+cd,但是實際上字串"ab\ncd"中並不包含「換行」這個字元,輸出的換行只是echo命令解析的結果。
# a="ab\ncd"#
echo
"length of var a is $
"length of var a is
6
通過$的形式可以得到乙個字串的長度,上面示例可以看出來,字串"ab\ncd"的長度是6而不是預期的5。
那麼能否將不可列印的字元賦值給變數呢?答案是肯定的:
# a=$'\x61\n\x62'#
echo"$a
"ab
請注意一定用的是單引號「'」,用雙引號括起來是不起轉義作用的。
變數值字元擷取:
a="abcdefg
"echo $
#cdefg
echo $
# cde
變數值字元刪除:(#為從頭部開始匹配,%為從尾部匹配,支援萬用字元「?*」)
a="abdcdefgh
"echo $ # 刪除字串頭部匹配「*d」的部分,萬用字元*代表匹配任意多個字元,乙個#號代表萬用字元「*」保守匹配
#cdefgh
echo $ # 兩個#號表示貪婪匹配
#efgh
echo $ # 同上,兩個%時代表貪婪匹配
# abdc
a=bb="abcdefg
"echo"$
"# defg
可以同時支援間接引用和字元刪除
用於賦值前檢查是否已經定義或賦值。
unset aunset b
b=""
# a沒有定義,b定義了但是空值
echo $ # 如果沒定義,則表示式採用預設值789
#789
echo $ # 如果沒定義或是空值,則表示式採用預設值789
#789
echo $ # 如果沒定義,則表示式採用預設值789,b定義了
#echo $ # 如果沒定義或是空值,則表示式採用預設值789
#789
echo
$a # 原變數並沒有被賦值
#echo
$b # 原變數並沒有被賦值
#b=123
echo $ # 如果變數已經被賦值,則不改變原有值
#123
unset aecho $ # 如果a沒定義,則表示式採用預設值,並給a賦值
#789
echo$a#
789# a已經被賦值了
a=""
echo $
#echo $ # 加冒號:的作用和之前一樣
#789
echo$a#
789
前面講了用「-」和「=」的,還有一種用「+」的,用於當變數已經被賦值的情況下採用預設值,舉一反三,不贅述了。
$0是檔名,$#代表引數個數,$1,$2等等表示執行該指令碼或函式後面跟的位置引數,$1代表第乙個引數,依次類推,需要注意的是,第9個以後的引數應該這麼表示:
$
這表示第10個引數,必須用花括號括起來,否則就變成第1個變數後面加個字元「0」了。因為這個有的人以為第9個以後的位置變數就不可用了,是錯的。
$@和$*都表示所有的變數,但是區別是前者將每個作為乙個字串,是多個字串的結合,而後者將所有變數組合成乙個字串,用空格分隔。
這樣不同會在for迴圈裡面造成使用的區別,在for迴圈裡面,如果加上引號 for i in"$@
" 和 for i in"$*
" 是不同的,前者還是會依次把引數代入迴圈,而後者會吧所有引數作為字串一次性代入:
echo'for i in"$@
"; do
echo"$i
"done
for i in"$*
"; do
echo"$i
"done
'> myscript.sh
chmod
755 myscript.sh
./myscript.sh abc 123
def
結果是:
abc123def
abc
123 def
那麼$@加引號和不加引號有區別麼?
大部分情況下結果看起來是一樣的,但會在某些情況下造成麻煩,因為for迴圈會用換行符「\n」和空格來拆分變數,所以如果呼叫指令碼所帶的引數中帶有空格或者換行符,不加引號的時候會把這個引數拆開了依次代入,而加了引號就可以避免這種情況。
echo'for i in"$@
"; do
echo"$i
"done
for i in $@ ; do
echo"$i
"done
'> myscript.sh
chmod
755 myscript.sh
./myscript.sh abc "
123 def
"
結果是:
abc123def
abc123
def
將陣列的值依次代入迴圈,可以用$和$這兩種方法,區別和加引號的區別同上面位置引數的使用相同。
shell的字串匹配通常是這樣的:
[ "abc" = "
abc"
]echo $?
# 0
$? 這個變數代表上條命令的返回碼。若字串相同則返回0,否則返回1。除了全匹配外,通過雙方括號「」還可以用正規表示式匹配
[[ "abc234def
" =~ ^abc[0-9][a-z]+$ ]]
echo $?
# 0
注意這裡正規表示式不能用引號括起來,而且只支援基本的正則,不支援如「\b \s」之類的擴充套件。
另單方括號『[ ]』和雙方括號『[[ ]]』的區別,單括號等同於bash內建test命令,雙方括號不是命令,是bash關鍵字。
linux shell 程式設計
bin bash comments your commands go here 首行中的符號 告訴系統其後路徑所指定的程式bash即是解釋此指令碼檔案的shell程式。除第一行外,以 開頭的行就是注釋行,直到此行的結束。如果一行未完成,可以在行尾加上 這個符號表明下一行與此行會合併為同一行。有環境變...
linux shell 程式設計
1 程式設計入門 shell的簡介。從程式設計師的角度來看,shell本身是一種用c語言編寫的程式,從使用者的角度來看,shell是使用者與linux作業系統溝通的橋梁。使用者既可以輸入命令執行,又可以利用 shell指令碼程式設計,完成更加複雜的操作。在linux gui日益完善的今天,在系統管理...
Linux Shell 程式設計
檔案描述 shell 代號 dev stdin 標準輸入,一般指的是鍵盤輸入 dev stdout 標準輸出,一般指終端顯示器 dev stderr 標準錯誤,一般指終端顯示器 l輸出重定向 l輸入重定向 l追加重定向 l錯誤重定向 2 l輸出和錯誤同時重定向 應用例子 1.將 ls的結果輸出到檔案...