shell script 學習

變量

  • Shell 是一個用 C 語言編寫的程序,它是用戶使用 Linux 的橋樑。
#!/bin/bash
# #! 告訴系統其後路徑所指定的程序即是解釋此腳本文件的 Shell 程序。

腳本運行方式:

  1. 作爲可執行程序
chmod +x ./test.sh
./test.sh
  1. 作爲解釋器參數
/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時,會同時存在三種變量:

  1. 局部變量 局部變量在腳本或命令中定義,僅在當前shell實例中有效,其他shell啓動的程序不能訪問局部變量。
  2. 環境變量 所有的程序,包括shell啓動的程序,都能訪問環境變量,有些程序需要環境變量來保證其正常運行。必要的時候shell腳本也可以定義環境變量。
  3. 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,這與我們熟悉的大多數編程語言不一樣。
  • 完整的表達式要被 包含,注意這個字符不是常用的單引號。

常見的運算有: +, -, *, /, %, =, ==, !=;值得注意的是:
條件表達式要放在方括號之間,並且要有空格,例如: [a==a==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;]
}
  1. 函數返回值在調用該函數後通過 $? 來獲得。
  2. 所有函數在使用前必須定義。這意味着必須將函數放在腳本開始部分,直至shell解釋器首次發現它時,纔可以使用。調用函數僅使用其函數名即可。
  3. 調用函數時可以向其傳遞參數。在函數體內部,通過 $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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章