複習

2020-08-13 00:20:27

#! 是一個約定的標記,它告訴系統這個指令碼需要什麼直譯器來執行,即使用哪一種 Shell

shell 變數:

name=」hauzai007」

echo $name

注意事項:

變數名和等號之間不能有空格

不能使用標點符號

不能使用bash裡的關鍵字

只讀變數:

name=」huazai007」

關鍵字:readonly name

刪除變數:

unset name

變數型別:

1 區域性變數:

區域性變數在指令碼或命令中定義,僅在當前shell範例中有效,其他shell啓動的程式不能存取區域性變數

2 環境變數:

所有的程式,包括shell啓動的程式,都能存取環境變數,有些程式需要環境變數來保證其正常執行。必要的時候shell指令碼也可以定義環境變數。

系統環境變數:

檢視所有環境變數:env

刪除環境變數:unset HAHA

舉個例子:

PPID:是當前進程的父進程的PID

PWD:當前工作目錄。

RANDO:亂數變數。每次參照這個變數會得到一個0~32767的亂數。

檢視所有環境變數:env

刪除環境變數:unset

用vim在/etc/profile檔案中新增我們想要的環境變數

設定新的環境變數
export 新環境變數名=內容
例:export MYNAME=」LLZZ」

生效:source /etc/profile

shell 字串

單引號和雙引號的區別:

單引號裡的任何字元都會原樣輸出,單引號字串中的變數是無效的;

雙引號的優點:

雙引號裡可以有變數
雙引號裡可以出現跳脫字元
獲取字串的長度:

str=」abcd」

echo ${#str}

測試字串

var=1234567890abcedef1203

1、使用#擷取0以後的內容

echo ${var#*0}

結果:abcedef1203

#表示操作符,*0表示從左往右找到第一個0,擷取0之後的所有字元

echo ${var##*0}

結果:3

#表示操作符,*0表示從右往左找到第一個0,擷取0之後的所有字元

2、使用%擷取

echo ${var%0*}

結果:1234567890abcedef12

%表示操作符,0*表示從右往左找到第一個0,擷取0之前的所有字元

echo ${var%%0*}

結果:123456789

%表示操作符,0*表示從左往右找到第一個0,擷取0之前的所有字元

3 根據索引來擷取

提取字串:

str=」abcd」

#表示從字串第二個字元開始擷取 ,取 4個字元

echo ${str:1:4}

echo ${var:0-2} 取後兩個

shell 陣列

定義陣列

arr=(aa bb cc)

讀取陣列

echo ${arr[0]}

獲取陣列的所有元素

echo ${arr[@]}

echo ${arr[*]}

獲取陣列的長度

echo ${#arr[@]}

shell 多行註釋:

:<<EOF

  xxxx

     xxxxx

EOF

shell 基本運算子

算數運算子

  • 加法
  • 減法
  • 乘法

/ 除法

% 取餘

= 賦值

== 比較(相等)

!= 不相等

關於計算:

[root@k8s-node1 ~]# a=echo "scale=2;3/10"|bc|awk -F '.' '{print $2}'
[root@k8s-node1 ~]# echo $a%
30%

[root@k8s-node1 ~]# echo $[10*20]
200

[root@localhost ~]# expr 10 + 20
30
[root@localhost ~]# echo $((10+30))
40
[root@localhost ~]# n=10
[root@localhost ~]# let n++
[root@localhost ~]# echo $n
11
[]和[[]]區別
[[]]更強大,支援字串的模式匹配(使用=~操作符時甚至支援shell的正則表達式)
[root@localhost ~]# sh t.sh
包含
[root@localhost ~]# cat t.sh
#!/bin/bash
a=「xxoo」
if [[ $a =~ 「x」 ]]; then
echo 「包含」
else
echo 「不包含」
fi

關係運算符

關係運算符只支援數位,不支援字串,除非字串的值是數位

-eq 是否相等

-ne 是否不相等

-gt 表示大於

-lt 表示小於

-ge 大於等於

-le 小於等於

布爾運算子

-o 或運算 兩個表達式只要有一個是true 就返回true

[ $a -lt 20 -o $b -gt 100 ] 返回 true

-a 與運算 兩個表達式都爲true才返回true

[ $a -lt 20 -a $b -gt 100 ] 返回 false

邏輯運算子

&& 等同於 –a

|| 等同於-o

if [[ $a –lt $b && $b –gt 100 ]]; then

  echo 「」

else

  echo 「」

fi

字串運算子

=: 檢測兩個字元是否相等

!=: 檢測兩個字元不相等

-z : 是否爲空

-n :字串的長度是否爲0

檔案測試運算子

-b 檢測檔案是否爲塊裝置: /dev/cdrom

-c 檢測檔案是否是字元裝置檔案 /dev/pts/0 (僞終端)

-d 是否爲目錄

-f 是否爲普通檔案

-r 是否可讀

-w 是否可寫

-x 是否可執行

=====================

4 爲SUID
2 爲SGID
1 爲SBIT
-u 檢測檔案是否設定了SUID位

[root@localhost tmp]# chmod 6444 aa.txt
[root@localhost tmp]# ll aa.txt
-r-Sr-Sr–. 1 root root 0 2月 11 06:44 aa.txt

-g 檢測檔案是否設定了 SGID 位

=====================

shell echo 命令

name=」huazai007」

echo –e 「$name \n」

-e 開啓跳脫

\n 換行

printf

%s 將參數按字面意思解釋爲字串

字元是單個字元,而字串包含一個或者多個字元

%c 字元

printf 「%-10s\n」 huazai007

-10s 指一個寬度爲10個字元(-表示左對齊,沒有則表示右對齊),任何字元都會被顯示在10個字元寬的字元內,如果不足則自動以空格填充,超過也會將內容全部顯示出來。

%f 將參數按浮點數列印

%-4.2 小數點後面保留兩位小數

左對齊看不出效果

shell 流程控制

#!/bin/bash

a=30

b=50

if [ $a == $b ]; then

  echo "a等於b"

elif [ $a -gt $b ]; then

  echo "a大於b"

elif [ $a -lt $b ]; then

  echo "a小於b"

else

  echo "沒有符合的條件"

fi

#!/bin/bash

:<<EOF

for i in {1…100}

do

  echo $i

done

EOF

for i in seq 1 100

do

  echo $i

done

=====while=

#!/bin/bash

int=0

while (($int<=5))

do

    echo $int

    #let "int++"

    let int=int+1

done

[root@master ~]# cat while_true.sh

#!/bin/bash

:<<EOF

while :

do

  echo "xx"

done

EOF

while true

do

  echo "oo"

done

[root@master ~]# cat until.sh

#!/bin/bash

a=0

until [ $a -gt 10 ]

do

  echo $a

  a=`expr $a + 1`

done

[root@master ~]# cat case.sh

#!/bin/bash

echo 「輸入一個1到4之間的數位」

echo 「你輸入的數位爲:」

read num

case $num in

  1)

  echo "1"

  ;;

  2)

  echo "2"

  ;;

  3)

  echo "3"

  ;;

  *)

  echo "你輸入的數位有誤!請重新輸入"

  ;;

esac

break命令
break命令允許跳出所有回圈(終止執行後面的所有回圈)。下面 下麪的例子中,指令碼進入死回圈直至使用者輸入數位大於5。要跳出這個回圈

continue
continue命令與break命令類似,只有一點差別,它不會跳出所有回圈,僅僅跳出當前回圈

for i in seq 10
do
if [ $i -eq 5 ]; then
#continue
break
fi
echo $i
done

int=0
while true
do
let int++
if [ $int -lt 10 ]; then
echo $int
else
break
fi
done

#!/bin/bash
for ((a=1;a<10;a++))
do
echo 「Outer loop: $a」
for ((b=1;b<10;b++))
do
if [ $b -eq 4 ]
then
#break
#break 2
#continue
continue 2
else
echo 「Inner loop: $b」
fi
done
done
continue N 將會把N層回圈剩餘程式碼都去掉

Shell程式設計中Shift的用法

位置參數可以用shift命令左移。比如shift 3表示原來的$4現在變成$1,原來的$5現在變成$2等等,原來的$1、$2、$3丟棄,$0不移動。

不帶參數的shift命令相當於shift 1。

當 Shell 程式不知道參數個數時,可以把所有參數一起賦值給變數$*。若使用者要求 Shell 在不知道位置變數個數的情況下,還能逐個的把參數一一處理,也就是在 $1 後爲 $2,在 $2 後面爲 $3 等。在 shift 命令執行前變數 $1 的值在 shift 命令執行後就不可用了。

範例如下:

#測試 shift 命令(x_shift.sh)
until [ $# -eq 0 ]
do
echo 「第一個參數爲: $1 參數個數爲: $#」
shift
done
執行以上程式x_shift.sh:
$./x_shift.sh 1 2 3 4

結果顯示如下:

第一個參數爲: 1 參數個數爲: 4
第一個參數爲: 2 參數個數爲: 3
第一個參數爲: 3 參數個數爲: 2
第一個參數爲: 4 參數個數爲: 1

從上可知 shift 命令每執行一次,變數的個數($#)減一,而變數值提前一位,下面 下麪程式碼用 until 和 shift 命令計算所有命令列參數的和。

++++++++++++++++++++++++++++++++++++++

shell裡的local

作用:一般用於shell內區域性變數的定義,多使用在函數內部

關於區域性變數和全域性變數:
(1)shell 指令碼中定義的變數是global的,作用域從被定義的地方開始,一直到shell結束或者被顯示刪除的地方爲止。
(2)shell函數定義的變數也是global的,其作用域從 函數被呼叫執行變數的地方 開始,到shell或結束或者顯示刪除爲止。函數定義的變數可以是local的,其作用域侷限於函數內部。但是函數的參數是local的。
(3)如果區域性變數和全域性變數名字相同,那麼在這個函數內部,會使用區域性變數。

#!/bin/bash
func1(){
local str
str=1echo"1 echo "str,func1"
}
func1 huazai
echo $str