變量
- Shell 是一個用 C 語言編寫的程序,它是用戶使用 Linux 的橋樑。
#!/bin/bash
# #! 告訴系統其後路徑所指定的程序即是解釋此腳本文件的 Shell 程序。
腳本運行方式:
- 作爲可執行程序
chmod +x ./test.sh
./test.sh
- 作爲解釋器參數
/bin/bash test.sh
/bin/sh test.sh
/bin/php test.php
- 定義變量時,變量名不加美元符號($,PHP語言中變量需要)
## 聲明變量
test_name="mobro.site"
for file in `ls /etc`
for file in $(ls /etc)
## 使用變量
echo $test_name
echo ${test_name} # 爲了幫助解釋器識別變量的邊界
# eg
for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done
readonly test_name # 將 test_name 變成只讀變量
unset test_name # 刪除變量;unset 不能刪除只讀變量
變量類型
運行shell時,會同時存在三種變量:
- 局部變量 局部變量在腳本或命令中定義,僅在當前shell實例中有效,其他shell啓動的程序不能訪問局部變量。
- 環境變量 所有的程序,包括shell啓動的程序,都能訪問環境變量,有些程序需要環境變量來保證其正常運行。必要的時候shell腳本也可以定義環境變量。
- shell變量 shell變量是由shell程序設置的特殊變量。shell變量中有一部分是環境變量,有一部分是局部變量,這些變量保證了shell的正常運行
- 單引號裏的任何字符都會原樣輸出,單引號字符串中的變量是無效的;雙引號裏可以有變量,雙引號裏可以出現轉義字符
greeting="hello, "$test_name" !" # 字符串拼接
echo ${#greeting} # 獲取字符串長度
echo ${greeting:1:4} # 提取字符
echo `expr index "$greeting" el` # 查找 el 的位置(先找到哪個字符就先計算哪個)
- bash支持一維數組(不支持多維數組),並且沒有限定數組的大小。
## 定義數組的形式 =>>>> 數組名=(值1 值2 ... 值n)
array=(
1
2
3)
array1=(1 2 3)
array[3]=4
array[4]=5
## 讀數組
val=${array[0]}
echo $val
echo $array[@] # 獲取整個數組
echo `length: "${#array[@]}"` # 獲取數組長度
echo `length: "${#array[*]}"` # 獲取數組長度
echo `length: "${#array[2]}"` # 獲取數組第二元素的長度
## 多行註釋 EOF可以爲其他任意符號
:<< EOF
註釋內容...
註釋內容...
EOF
:<<'
還是註釋...
'
shell 傳遞參數
腳本內獲取參數的格式爲:$n。n 代表一個數字,1 爲執行腳本的第一個參數,2 爲執行腳本的第二個參數
# Shell 傳遞參數實例!
chmod +x test.sh
./test.sh 1 2 3
:<< '
第一個參數爲:1
第二個參數爲:2
第三個參數爲:3
'
$# # 傳遞到腳本的參數個數
$* # 以一個單字符串顯示所有向腳本傳遞的參數。
# 如"$*"用「"」括起來的情況、以"$1 $2 … $n"的形式輸出所有參數。
$$ # 腳本運行的當前進程 ID
$@ # 以一個單字符串顯示所有向腳本傳遞的參數。
# 如"$*"用「"」括起來的情況、以"$1" "$2" … "$n"的形式輸出所有參數。
$- # 顯示 shell 使用的當前選項
$? # 顯示最後命令的退出狀態。0 表示沒有錯誤,其他表示有錯誤
$*
和 $@
區別: 假設在腳本運行時寫了三個參數 1、2、3,,則 " * " 等價於 “1 2 3”(傳遞了一個參數),而 “@” 等價於 “1” “2” “3”(傳遞了三個參數)。看如下代碼:
echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done
執行結果:
$ chmod +x test.sh
$ ./test.sh 1 2 3
– $* 演示 —
1 2 3
– $@ 演示 —
1
2
3
shell 運算符
#!/bin/bash
val=`expr 2 + 2`
echo "2 + 2 = $val"
- 表達式和運算符之間要有空格,例如 2+2 是不對的,必須寫成 2 + 2,這與我們熟悉的大多數編程語言不一樣。
- 完整的表達式要被
包含,注意這個字符不是常用的單引號。
常見的運算有: +
, -
, *
, /
, %
, =
, ==
, !=
;值得注意的是:
條件表達式要放在方括號之間,並且要有空格,例如: [b] 是錯誤的,必須寫成 [ $a == $b ]
val1=`expr 2 \* 2`
val2=`expr 2 / 2`
#:<< eof
val3=[ $val2 == 1 ]
echo "$val3"
上面個這是一種錯誤寫法,不能使用 `val3=[ $val2 == 1 ]` 這種寫法, 一般 == 或者 != 是用於條件判斷時用
#eof
if [ $val2 == 1 ]
then
echo "val2 = $val2"
fi
- 在 MAC 中 shell 的 expr 語法是:$((表達式)),此處表達式中的 “*” 不需要轉義符號 “” 。
- 乘號(*)前邊必須加反斜槓()才能實現乘法運算;
常見的關係運算符:
關係運算符只支持數字,不支持字符串,除非字符串的值是數字。
# -eq 相等
# -ne 不相等
# -gt 左 大於 右
# -lt 左 小於 右
# -ge 左 大於等於 右
# -le 左 小於等於 右
if [ $a -eq $b ]
then
echo "$a -eq $b: a 等於 b"
else
echo "不等於"
fi
常見的布爾運算
# ! 非運算
# -o 或運算
# -a 與運算
a=99
b=15
if [ $a -lt 100 -a $b -ge 15 ]
then
echo "是的,滿足條件"
fi
常見的邏輯運算
# && 邏輯and
# || 邏輯or
a=99
b=15
# if [ $a -lt 100 && $b -ge 15 ] # 這樣寫是不合理的,應該如下寫。但是爲何呢?
if [[ $a -lt 100 && $b -ge 15]]
then
echo " ----- true "
fi
echo 命令
- echo 的
""
是可以省略的 - read 命令從標準輸入中讀取一行,並把輸入行的每個字段的值指定給 shell 變量
# -e 開啓轉義
# 顯示結果指定到某個文件
echo "it's a test" > log
# 取日期
echo `date +%y-%m-%d`
read firstStr secondStr # read 命令一個一個詞組地接收輸入的參數,每個詞組需要使用空格進行分隔;如果輸入的詞組個數大於需要的參數個數,則多出的詞組將被作爲整體爲最後一個參數接收。
# 實例,test.sh 代碼:
read -p "請輸入一段文字:" -n 6 -t 5 -s password
echo -e "\npassword is $password"
# -p 輸入提示文字
# -n 輸入字符長度限制
# -t 輸入限時
# -s 隱藏輸入內容
printf 命令
- 相比於 echo 移植性更好。
- 使用引用文本或空格分隔的參數,外面可以在 printf 中使用格式化字符串,還可以制定字符串的寬度、左右對齊方式等。默認 printf 不會像 echo 自動添加換行符,我們可以手動添加 \n。
# printf 語法
printf format-string [arguments...]
# format-string 格式控制字符串
printf "%-10s %-8s %-4s\n" 姓名 性別 體重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 楊過 男 48.6543
printf "%-10c %-8s %-4.2f\n" 郭芙 女 47.9876
%s %c %d %f都是格式替代符
%-10s 指一個寬度爲10個字符(-表示左對齊,沒有則表示右對齊),任何字符都會被顯示在10個字符寬的字符內,如果不足則自動以空格填充,超過也會將內容全部顯示出來。
%-4.2f 指格式化爲小數,其中.2指保留2位小數。
test 命令
用於檢查某個條件是否成立,它可以進行數值、字符和文件三個方面的測試。
在代碼中 [] 執行基本的算數運算。
num1=100
num2=100
if test ${num1} -eq $[num2]
then
printf "\n -------- 分割線 -------- \n%s == %s" $num1 $num2
else
echo '不等'
fi
結果如下:
?? 爲什麼結果最後有個 % 呢?
?? -eq, =, == 在 test 命令中好像是通用的
流程控制
- if else if else
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
- 循環
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
# 寫成一行
for var in item1 item2 ... itemN; do command1; command2; ... done;
# while 循環
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
# eg:
for loop in 1 2 3 4 5
do
echo "$loop"
done
# until 循環
# until 循環執行一系列命令直至條件爲 true 時停止。
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
使用中使用了 Bash let 命令,它用於執行一個或多個表達式,變量計算中不需要加上 $ 來表示變量
- 無限循環
while :
do
command
done
while true
do
command
done
for (( ; ; ))
- case
取值後面必須爲單詞in,每一模式必須以右括號結束。取值可以爲變量或常數。匹配發現取值符合某一模式後,其間所有命令開始執行直至 ;;。
取值將檢測匹配的每一個模式。一旦模式匹配,則執行完匹配模式相應命令後不再繼續其他模式。如果無一匹配模式,使用星號 * 捕獲該值,再執行後面的命令。
echo '輸入 1 到 4 之間的數字:'
echo '你輸入的數字爲:'
read aNum
case $aNum in
1) echo '你選擇了 1'
;;
2) echo '你選擇了 2'
;;
3) echo '你選擇了 3'
;;
4) echo '你選擇了 4'
;;
*) echo '你沒有輸入 1 到 4 之間的數字'
;;
esac
- 跳出循環
在循環過程中,有時候需要在未達到循環結束條件時強制跳出循環,Shell使用兩個命令來實現該功能:break和continue。
shell 函數
1、可以帶function fun() 定義,也可以直接fun() 定義,不帶任何參數。
2、參數返回,可以顯示加:return 返回,如果不加,將以最後一條命令運行結果,作爲返回值。 return後跟數值n(0-255)
[ function ] funname [()]
{
action;
[return int;]
}
- 函數返回值在調用該函數後通過
$?
來獲得。 - 所有函數在使用前必須定義。這意味着必須將函數放在腳本開始部分,直至shell解釋器首次發現它時,纔可以使用。調用函數僅使用其函數名即可。
- 調用函數時可以向其傳遞參數。在函數體內部,通過 $n 的形式來獲取參數的值
funWithParam()
{
echo "第一個參數爲 $1 !"
echo "第二個參數爲 $2 !"
echo "第十個參數爲 $10 !"
echo "第十個參數爲 ${10} !"
echo "第十一個參數爲 ${11} !"
echo "參數總數有 $# 個!"
echo "作爲一個字符串輸出所有參數 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73