輸出重定向:
>> $HOME/log/SB-`date +%Y%m%d`.log 2>&1
1.定義變量
定義變量時,變量名不加美元符號($),如:
hellosb=“sb”;
注意,變量名和等號之間不能有空格,這可能和你熟悉的所有編程語言都不一樣。同時,變量名的命名須遵循如下規則:
- 首個字符必須爲字母(a-z,A-Z)。
- 中間不能有空格,可以使用下劃線(_)。
- 不能使用標點符號。
- 不能使用bash裏的關鍵字(可用help命令查看保留關鍵字)。
使用一個定義過的變量,只要在變量名前面加美元符號($)即可,如
hellosb=“sb”;
echo $hellosb
echo ${hellosb}
3.重新定義變量
已定義的變量,可以被重新定義,如
hellosb=“sb”
echo ${hellosb}
hellosb="you are sb"
echo ${hellosb}
4.只讀變量
使用 readonly 命令可以將變量定義爲只讀變量,只讀變量的值不能被改變。
#!/bin/bash
hellosb="sb"
readonly hellosb
hellosb="you are sb"
運行腳本,結果如下:
./biubiu.sh: 第 6 行:unset: hellosb: 無法反設定: 只讀 variable
5.刪除變量
使用 unset 命令可以刪除變量。
#!/bin/bash
hellosb="sb"
unset hellosb
echo ${hellosb}
運行腳本,沒有任何輸出
6.特殊變量
$* 和 $@ 的區別
$* 和 $@ 都表示傳遞給函數或腳本的所有參數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有參數。但是當它們被雙引號(" ")包含時,"$*" 會將所有的參數作爲一個整體,以"$1 $2 … $n"的形式輸出所有參數;"$@" 會將各個參數分開,以"$1" "$2" … "$n" 的形式輸出所有參數。
7.命令替換
命令替換是指Shell可以先執行命令,將輸出結果暫時保存,在適當的地方輸出。
命令替換語法:
`commnd`
注意是反引號,不是單引號,這個鍵位於 Esc 鍵下方。
#!/bin/bash
DATE=`date`
echo"當前時間是 $DATE"
運行腳本:
8.變量替換
9.運算符
expr 是一款表達式計算工具,使用它能完成表達式的求值操作。
例如,兩個數相加:
#!/bin/bash
val=`expr 2 + 2`
echo "Total value : $val"
運行腳本輸出:
Total value : 4
兩點注意:
- 表達式和運算符之間要有空格,例如 2+2 是不對的,必須寫成 2 + 2,這與我們熟悉的大多數編程語言不一樣。
- 完整的表達式要被 ` ` 包含,注意這個字符不是常用的單引號,在 Esc 鍵下邊
10.註釋
以“#”開頭的行就是註釋,會被解釋器忽略。sh裏沒有多行註釋,只能每一行加一個#號。但是可以把需要註釋的部分定義成函數,不調用這個函數,就能達到註釋的目的。如
#!/bin/bash
nofunction(){
echo "hello"
}
執行腳本,沒有輸出;
11.字符串
單引號:
單引號字符串的限制:
- 單引號裏的任何字符都會原樣輸出,單引號字符串中的變量是無效的;
- 單引號字串中不能出現單引號(對單引號使用轉義符後也不行)
雙引號的優點:
- 雙引號裏可以有變量
- 雙引號裏可以出現轉義字符
獲取、提取、查找字符串長度:
12.數組
bash支持一維數組(不支持多維數組),並且沒有限定數組的大小。類似與C語言,數組元素的下標由0開始編號。獲取數組中的元素要利用下標,下標可以是整數或算術表達式,其值應大於或等於0。
定義數組
在Shell中,用括號來表示數組,數組元素用“空格”符號分割開。定義數組的一般形式爲:
array_name=(value1 ... valuen)
讀取數組
讀取數組元素值的一般格式是:
${array_name[index]}
獲取數組長度
獲取數組長度的方法與獲取字符串長度的方法相同,例如:
# 取得數組元素的個數
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得數組單個元素的長度
lengthn=${#array_name[n]}
13.echo
顯示轉義字符
echo "\"hello world\""
執行腳本,輸出
"hello world"
輸出換行\n
echo "hello!\n"
echo "world"
執行結果 hello
world
輸出不換行\c
echo "hello!\c"
echo "world" 執行結果helloworld
原樣輸出
echo '$name\"' 執行結果 'sb'
從上面可看出,雙引號可有可無,單引號主要用在原樣輸出中。
14.printf 格式化輸出
printf 命令用於格式化輸出, 是echo命令的增強版。它是C語言printf()庫函數的一個有限的變形,並且在語法上有些不同。注意:printf 由 POSIX 標準所定義,移植性要比 echo 好。
如同 echo 命令,printf 命令也可以輸出簡單的字符串:
printf "Hello, Shell\n"
Hello, Shell
printf 不像 echo 那樣會自動換行,必須顯式添加換行符(\n)。
printf 命令的語法:
printf format-string [arguments...]
format-string 爲格式控制字符串,arguments 爲參數列表。
printf()在C語言入門教程中已經講到,功能和用法與 printf 命令類似,請查看:C語言格式輸出函數printf()詳解
這裏僅說明與C語言printf()函數的不同:
- printf 命令不用加括號
- format-string 可以沒有引號,但最好加上,單引號雙引號均可。
- 參數多於格式控制符(%)時,format-string 可以重用,可以將所有參數都轉換。
- arguments 使用空格分隔,不用逗號。
# format-string爲雙引號
printf "%d %s\n" 1 "hello"
1 hello
# 單引號與雙引號效果一樣
printf '%d %s\n' 1 "hello"
1 hello
# 沒有引號也可以輸出
printf %s hello
hello
# 格式只指定了一個參數,但多出的參數仍然會按照該格式輸出,format-string 被重用
printf %s abc def
abcdef
printf "%s\n" abc def
abc
def
printf "%s %s %s\n" a b c d e f g h i j
a b c
d e f
g h i
j
# 如果沒有 arguments,那麼 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
and 0
# 如果以 %d 的格式來顯示字符串,那麼會有警告,提示無效的數字,此時默認置爲 0
printf "The first program always prints'%s,%d\n'" Hello Shell
-bash: printf: Shell: invalid number
The first program always prints 'Hello,0'
注意,根據POSIX標準,浮點格式%e、%E、%f、%g與%G是“不需要被支持”。這是因爲awk支持浮點預算,且有它自己的printf語句。這樣Shell程序中需要將浮點數值進行格式化的打印時,可使用小型的awk程序實現。然而,內建於bash、ksh93和zsh中的printf命令都支持浮點格式。
14.if else語句
if 語句通過關係運算符判斷表達式的真假來決定執行哪個分支。Shell 有三種 if ... else 語句:
- if ... fi 語句;
- if ... else ... fi 語句;
- if ... elif ... else ... fi 語句。
1) if ... else 語句
if ... else 語句的語法:if [ expression ]
then
Statement(s) to be executed if expression is true
fi
如果 expression 返回 true,then 後邊的語句將會被執行;如果返回 false,不會執行任何語句。
最後必須以 fi 來結尾閉合 if,fi 就是 if 倒過來拼寫,後面也會遇見。
注意:expression 和方括號([ ])之間必須有空格,否則會有語法錯誤。
2) if ... else ... fi 語句
if ... else ... fi 語句的語法:if [ expression ]
then
Statement(s) to be executed if expression is true
else
Statement(s) to be executed if expression is not true
fi
如果 expression 返回 true,那麼 then 後邊的語句將會被執行;否則,執行 else 後邊的語句。
3) if ... elif ... fi 語句
if ... elif ... fi 語句可以對多個條件進行判斷,語法爲:if [ expression 1 ]
then
Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
Statement(s) to be executed if expression 3 is true
else
Statement(s) to be executed if no expression is true
fi
哪一個 expression 的值爲 true,就執行哪個 expression 後面的語句;如果都爲 false,那麼不執行任何語句。
if ... else 語句也可以寫成一行,以命令的方式來運行,像這樣:
if test $[2*3] -eq $[1+5]; then echo '這個兩個相等!'; fi;
test 命令用於檢查某個條件是否成立,與方括號([ ])類似。
16. case esac語句
case 語句匹配一個值或一個模式,如果匹配成功,執行相匹配的命令。case語句格式如下:
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac
取值將檢測匹配的每一個模式。一旦模式匹配,則執行完匹配模式相應命令後不再繼續其他模式。如果無一匹配模式,使用星號 * 捕獲該值,再執行後面的命令。
case $option in
-f) FILE="$2"
echo "File name is $FILE"
;;
-d) DIR="$2"
echo "Dir name is $DIR"
;;
*)
echo "`basename $0`:usage: [-f file] | [-d directory]"
exit 1 # Command to come out of the program with status 1
;;
esac
File name is ab
[root@localhost shell]# ./biubiu.sh -d cd
Dir name is cd
17. for循環
for 變量 in 列表
do
command1
command2
...
commandN
done
列表是一組值(數字、字符串等)組成的序列,每個值通過空格分隔。每循環一次,就將列表中的下一個值賦給變量。
in 列表是可選的,如果不用它,for 循環使用命令行的位置參數。
例如,順序輸出當前列表中的數字:
for sb in 1 2 3 4 5
do
echo "The value is: $sb"
done
執行腳本,結果如下:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
do
Statement(s) to be executed if command is true
done
命令執行完畢,控制返回循環頂部,從頭開始直至測試條件爲假。
while循環可用於讀取鍵盤信息。
19.until
until 循環執行一系列命令直至條件爲 true 時停止。until 循環與 while 循環在處理方式上剛好相反。一般while循環優於until循環,但在某些時候,也只是極少數情況下,until 循環更加有用
until 循環格式爲:
until command
do
Statement(s) to be executed until command is true
done
command 一般爲條件表達式,如果返回值爲 false,則繼續執行循環體內的語句,否則跳出循環。
20.break 與continue
break命令允許跳出所有循環(終止執行後面的所有循環)。
continue命令與break命令類似,只有一點差別,它不會跳出所有循環,僅僅跳出當前循環。
21.函數
hell 函數的定義格式如下:
function_name () {
list of commands
[ return value ]
}
如果你願意,也可以在函數名前加上關鍵字 function:
function function_name () {
list of commands
[ return value ]
}
函數返回值,可以顯式增加return語句;如果不加,會將最後一條命令運行結果作爲返回值。
Shell 函數返回值只能是整數,一般用來表示函數執行成功與否,0表示成功,其他值表示失敗。如果 return 其他數據,比如一個字符串,往往會得到錯誤提示:“numeric argument required”。
調用函數只需要給出函數名,不需要加括號。
像刪除變量一樣,刪除函數也可以使用 unset 命令,不過要加上 -f 選項,如下所示:$unset -f function_name
函數參數
注意,$10 不能獲取第十個參數,獲取第十個參數需要${10}。當n>=10時,需要使用${n}來獲取參數