1. 程式人生 > >SHELL指令碼------基礎知識

SHELL指令碼------基礎知識

一、shell的簡單瞭解

一、什麼是shell?

shell也是作業系統中的一個軟體,它包在linux核心的外面,為使用者和核心之間的互動提供了一個介面,系統中的命令用shell去解釋shell接受系統迴應的輸出並顯示其到螢幕中。

二、什麼是shell指令碼?

1.簡單的說,當命令或者程式不在命令列執行,而是通過一個程式檔案來執行,這個程式就被稱為shell指令碼。

2.也就是在shell腳本里內建了多條命令,語句,迴圈控制,然後將這些命令一次性執行完畢,這種通過檔案執行命令的方式稱為非互動式。

三、為什麼使用shell指令碼?

1.適合處理作業系統底層的業務,有眾多系統命令為其做支撐(還有文字處理三兄弟grep,sed,awk)

2.適合處理純文字檔案,linux中許多服務配置檔案,啟動指令碼,都是純文字(httpd,nfs,mysql,nginx,lvs)

3.linux系統指令碼用shell開發更簡單

四、如何檢視系統預設shell?

五、指令碼的開發規範

1.第一行:#!/bin/bash
    指定直譯器:由哪個程式來執行指令碼內容
    #!:幻數

2.指令碼資訊

#!/bin/bash
#Date:2018-12-25
#Author: westos-wsp
#Connect: [email protected]


#Desc: This scripts is for...
#Version:1.0

3.指令碼名最好以 .sh 結尾

六、 指令碼執行方法

1.sh script.sh | bash script.sh    沒有執行許可權時

2.path/script.sh | ./script.sh    絕對路徑,當前目錄下(絕對路徑,需要給指令碼新增執行許可權)

3.source script.sh | . script.sh    這種方式會使用source或.號來讀如指定shell檔案,並會把其他shell中的變數值或函式返回給父shell繼續使用

前兩種方式,在執行指令碼的時候,會預設開啟一個新的shell,而新shell的變數值和函式不會返回給父shell

二、定義變數

一、普通變數

普通變數賦值
變數名=hello
變數名=‘hello’
變數名=“hello”

[[email protected] ~]# a=hello
[[email protected] ~]# echo $a
hello
[[email protected] ~]# b='hello'
[[email protected] ~]# echo $b
hello
[[email protected] ~]# c="hello"
[[email protected] ~]# echo $c
hello
[[email protected] ~]# a=westos-$a
[[email protected] ~]# echo $a
westos-hello
[[email protected] ~]# b='westos-$a'   沒有轉譯變數,按原樣輸出
[[email protected] ~]# echo $b
westos-$a
[[email protected] ~]# c="westos-$a"   當轉譯變數時要加雙引號
[[email protected] ~]# echo $c
westos-westos-hello
[[email protected] ~]# a=westos hello   當定義變數有空格時要加雙引號
bash: hello: command not found...
[[email protected] ~]# a="westos hello"
[[email protected] ~]# echo $a
westos hello


注意:建議沒有特別要求時,字串都加雙引號,需要原樣輸出就加單引號。

2. 將命令的結果賦值給變數:
  變數名 = 命令
   b=ls或 b=$(ls)

二、特殊變數

$0:獲取shell指令碼檔名,如果執行時包含路徑,則輸出指令碼路徑
$n(>0):獲取指令碼的第n個引數
$#:獲取指令碼引數的總個數
$*:獲取所有引數
[email protected]:獲取所有引數
$?:表示上條命令執行結果的返回值,0表示執行成功,非0表示執行失敗
$$:獲取當前shell程序號

$0:

[[email protected] mnt]# cat westos.sh 
#!/bin/bash
echo $0
[[email protected] mnt]# sh westos.sh 
westos.sh
[[email protected] mnt]# /mnt/westos.sh 
/mnt/westos.sh

$n(>0):

[[email protected] mnt]# cat pash.sh 
#!/bin/bash
echo $1 $2
[[email protected] mnt]# sh pash.sh hello westos
hello westos
[[email protected] mnt]# sh pash.sh westos hello
westos hello
[[email protected] mnt]# sh pash.sh redhat westos
redhat westos
[[email protected] mnt]# echo  \${1..10} > pash.sh 
[[email protected] mnt]# cat pash.sh 
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10
[[email protected] mnt]# sh pash.sh {1..10}
1 2 3 4 5 6 7 8 9 10
[[email protected] mnt]# sh pash.sh {a..z}
a b c d e f g h i a0
[[email protected] mnt]# vim pash.sh 
[[email protected] mnt]# sh pash.sh {a..z}
a b c d e f g h i j
[[email protected] mnt]# cat pash.sh 
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}

$#

[[email protected] mnt]# vim pash.sh 
[[email protected] mnt]# sh pash.sh {1..100}
1 2 3 4 5 6 7 8 9 10
100
[[email protected] mnt]# cat pash.sh 
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
echo $#

三、read用法

[[email protected] mnt]# read str
westos hello
[[email protected] mnt]# echo $str 
westos hello
[[email protected] mnt]# read -p "請輸入一個整數:" i
請輸入一個整數:10
[[email protected] mnt]# echo $i
10
[[email protected] mnt]# read -p "請輸入一個整數:" i
請輸入一個整數:100
[[email protected] mnt]# echo $i
100

四、打包日誌

三、變數的數值計算

一、expr命令

注意 * 直接用不能識別,需要進行轉譯,才可以執行,即在*前加\。

[[email protected] mnt]# a=123
[[email protected] mnt]# expr $a + 10
133
[[email protected] mnt]# expr $a - 10
113
[[email protected] mnt]# expr $a \* 10
1230
[[email protected] mnt]# expr $a / 10
12
[[email protected] mnt]# expr $a % 10
3

二、$[]$(())表示式

[[email protected] mnt]# a=10
[[email protected] mnt]# echo $[a+10]
20
[[email protected] mnt]# echo $[a-10]
0
[[email protected] mnt]# echo $[a*10]
100
[[email protected] mnt]# echo $[a/10]
1
[[email protected] mnt]# echo $[a%10]
0
[[email protected] mnt]# echo $((a+10))
20
[[email protected] mnt]# echo $((a-10))
0
[[email protected] mnt]# echo $((a*10))
100
[[email protected] mnt]# echo $((a/10))
1
[[email protected] mnt]# echo $((a%10))
0

三、 let命令

注意:let命令在執行後會儲存新的值

[[email protected] mnt]# let a+=10
[[email protected] mnt]# echo $a
20
[[email protected] mnt]# let a-=10
[[email protected] mnt]# echo $a
10
[[email protected] mnt]# let a*=10
[[email protected] mnt]# echo $a
100
[[email protected] mnt]# let a/=10
[[email protected] mnt]# echo $a
10
[[email protected] mnt]# let a%=10
[[email protected] mnt]# echo $a
0

四、小數運算工具bc

[[email protected] mnt]# echo 1.2+3.4 | bc
4.6
[[email protected] mnt]# echo 1.23+4.56 | bc
5.79
[[email protected] mnt]# echo "scale=4;1.23*4.56" | bc
5.6088
[[email protected] mnt]# echo "scale=2;1.23*4.56" | bc
5.60

五、練習題

寫指令碼計算兩個數的加減乘除

四、文字處理

一、grep,egrep

Grep定義

  • grep 命令是一種強大的文字搜尋工具,根據使用者指定的“模式”對目標文字進行匹配檢查,列印匹配到的行
  • 由正則表示式或者字元及基本文字字元所編寫的過濾條件
  • 全面搜尋研究正則表示式並顯示出來

Grep引數

-i    忽略字母大小寫
-v    條件取反
-c    統計匹配行數
-q    靜默,無任何輸出
-n    顯示匹配結果所在的行號

-q:

[[email protected] mnt]# grep '172.25.254.254' /etc/hosts && echo 'YES' || echo 'NO'
172.25.254.254 classroom.example.com
172.25.254.254 content.example.com
YES
[[email protected] mnt]# grep -q '172.25.254.254' /etc/hosts && echo 'YES' || echo 'NO'
YES

-c:

[r[email protected] mnt]# egrep -c '/sbin/nologin' /etc/passwd
34

基本元字元:^ $

[[email protected] mnt]# egrep '^root' /etc/passwd   匹配以字串 root 開頭
root:x:0:0:root:/root:/bin/bash
[[email protected] mnt]# vim wsp
[[email protected] mnt]# cat wsp 
root sbin
root sbin root
root sbin sbin
[[email protected] mnt]# egrep -m10 'sbin$' wsp      匹配以字串 sbin 結尾
root sbin
root sbin sbin

基本元字元:'.' 過濾非空行

[[email protected] mnt]# vim wsp 
[[email protected] mnt]# egrep '.' wsp 
root sbin
root sbin root
root sbin sbin
root
awd
awd
awd

過濾空行

[[email protected] mnt]# egrep -v '.' wsp 過濾空行
[[email protected] mnt]# egrep '^$' wsp   過濾空行  (開始結束)

基本元字元: + ? *

[[email protected] mnt]# vim 1.sh
[[email protected] mnt]# cat 1.sh 
color color color
colorful,color
color color.
colorfulful?
stuf
stuff
stufff
stuffff
stufawd

we adw  dfg  awda
xcvb  wewe  asdawd
weawe IPADDR
rere wewewe
westos wewewewe Shell
wea web wef

[[email protected] mnt]# egrep 'f+' 1.sh 輸出包括f,ff,fff...,即至少出現一次
colorful,color
colorfulful?
stuf
stuff
stufff
stuffff
stufawd
we adw  dfg  awda
wea web wef

[[email protected] mnt]# egrep 'color(ful)?' 1.sh  末尾的ful最多出現一次,也可以沒有
color color color
colorful,color
color color.
colorfulful?

元字元:{}

[[email protected] mnt]# egrep '(we){3}' 1.sh     精確匹配三個we所在行
rere wewewe
westos wewewewe Shell
[[email protected] mnt]# egrep '(we){2,4}' 1.sh   匹配2-4個we所在行
xcvb  wewe  asdawd
rere wewewe
westos wewewewe Shell
[[email protected] mnt]# egrep '(we){3,}' 1.sh    匹配3個及以上we所在行
rere wewewe
westos wewewewe Shell
[[email protected] mnt]# egrep '(we)[ab]' 1.sh    匹配we後為a或者b所在行
weawe IPADDR
wea web wef
[[email protected] mnt]# egrep '[A-Z]' 1.sh       匹配大寫字母所在行
weawe IPADDR
westos wewewewe Shell

二、cut命令

cut -d   指定分隔符
cut -d : -f 1-3 /etc/passwd  指定分隔符為:,顯示第1到3列
cut -c 1,4 /etc/passwd       顯示第一和第四個字元

三、練習

獲取主機ip

[[email protected] mnt]# ifconfig eth0 | grep "inet " | awk '{print $2}'
172.25.254.102
[[email protected] mnt]# ifconfig eth0 | grep "inet " | cut -d " " -f 10
172.25.254.102

檢測網路

[[email protected] mnt]# vim ping.sh
ping -c1 -w1 172.25.254.$1 &> /dev/null && echo 172.25.254.$1 is up || echo 172.25.254.$1 is down
[[email protected] mnt]# sh ping.sh 102
172.25.254.102 is up

四、sort命令:排序

引數:
-n    純數字排序
-r    倒序
-u   去掉重複數字
-o    輸出到指定檔案中
-t    指定分隔符
-k    指定要排序的列

注意: 預設以第一個數字排序

[[email protected] mnt]# sort wsp 

12
12
2
234
3
3
4
45
5
5
67
89
[[email protected] mnt]# sort  -n wsp 

2
3
3
4
5
5
12
12
45
67
89
234
[[email protected] mnt]# sort -u wsp 

12
2
234
3
4
45
5
67
89
[[email protected] mnt]# sort -nu wsp 

2
3
4
5
12
45
67
89
234
[[email protected] mnt]# sort -nt : -k 2 wsp 

2:2
3:3
3:4
4:4
5:7
67:23
12:34
45:34
234:56
12:87
5:88
89:89
[[email protected] mnt]# sort -nt : -k 2 wsp -o /mnt/file

五、uniq命令:對重複字元處理

uniq
     -u   顯示唯一的行
     -d   顯示重複的行
     -c   每行顯示一次並統計重複次數

[[email protected] mnt]# sort -n wsp | uniq -c
      1 
      1 2
      2 3
      1 4
      2 7
      2 8
      3 23
      2 34
      1 56
      1 87
      1 89
[[email protected] mnt]# sort -n wsp | uniq -d
3
7
8
23
34
[[email protected] mnt]# sort -n wsp | uniq -u

2
4
56
87
89

六、練習

將/tmp目錄中的檔案取出最大的

[[email protected] mnt]# ll /tmp/
total 0
drwx------. 2 root root 23 Dec 25 22:39 ssh-2XD2n4VLLlQy
drwx------. 3 root root 16 Dec 25 22:39 systemd-private-JdjClc
drwx------. 3 root root 16 Dec 25 22:38 systemd-private-oH8LTq
drwx------. 3 root root 16 Dec 25 22:38 systemd-private-u2FkuC
[[email protected] mnt]# ll /tmp | sort -nk 5 | cut -d " " -f 9 | tail -n 1
ssh-2XD2n4VLLlQy
[[email protected] mnt]# ls -Sl /tmp/ | head -2 | cut -d " " -f 9

ssh-2XD2n4VLLlQy

五、條件判斷

test "$a" == "$b" 等同於 [ "$a" == "$b" ]

[ "$a" = "$b" ]           等於
[ "$a" != "$b" ]          不等於
[ "$a" -eq "$b" ]        等於
[ "$a" -ne "$b" ]        不等於
[ "$a" -le "$b" ]         小於等於
[ "$a" -ge "$b" ]        大於等於
[ "$a" -gt "$b" ]         大於
[ "$a" -lt "$b" ]           小於
[ "$a" -ne "$b" -a "$a" -gt "$b" ]     -a必須條件都滿足
[ "$a" -ne "$b" -o"$a" -gt "$b" ]     -o條件至少滿足一個
[ -z "$a" ]          是否為空
[ -e "file" ]        是否存在
[ -f "file" ]         普通檔案
[ -b "file" ]        塊裝置
[ -S "file" ]        套接字
[ -c "file" ]        字元裝置
[ -L "file" ]        軟連結

練習:

判斷輸入的數字是否在10以內
1.輸入是否為空
2.是否在10以內
3.1<$a<10 --> yes
4.$a<1 $a>10 --> no

#!/bin/bash

[ -z "$1" ] && {
    echo "please input a number!"
    exit 1
}

[ "$1" -gt "0" -a "$1" -lt "10" ] && {
    echo "YES"
}||{
    echo "NO"
}

判斷檔案型別

#!/bin/bash

[ -z "$1" ] && {
        echo "Please input a file name after script!!"
        exit 1
}
[ -e "$1" ]||{
        echo "$1 is not exit!!"
        exit 1
}
[ -f "$1" ] &&{
        echo "$1 is a common file"
        exit 0
}
[ -L "$1" ] &&{
        echo "$1 is a link "
        exit 0
}
[ -b "$1" ] &&{
        echo "$1 is a block file"
        exit 0
}
[ -S "$1" ] &&{
        echo "$1 is a taojiezi"
        exit 0
}
[ -c "$1" ] &&{
        echo "$1 is a zifushebei"
        exit 0
}
[ -d "$1" ] &&{
        echo "$1 is a directory"
        exit 0
}