認識shell

一、認識shell

什么是shell?shell為單詞外殼的意思。那么這是誰的外殼?我們知道一個系統中實際工作的是那些硬件,cpu、內存、磁盤等。我們如何調用這些硬件為我們工作?實際上,硬件是由內核kernel控制的。我們可以通過kernel控制硬件,但我們不能直接和內核kernel交流。我們需要一個外殼,這個外殼就是shell來溝通kernel。何為shell腳本,其實不過是一堆命令寫在一個文件中,這個文件具有執行權限。

二、變量

什么是變量?變量是腳本編程中數據表現的一中方法,變量是系統為了保留數據項在內存空間中分配一個位置或者一組位置的標識或名字。bash變量是不區分類型的,本質上都是字符串。

2.1 特殊的變量類型

本地變量:只對當前的shell進程有效,對其它shell進程無效,包含當前shell進程的子進程

[leon@localhost ~]$ test=string                                    #定義一個本地變量
[leon@localhost ~]$ echo $test
string
[leon@localhost ~]$ bash                                            #打開一個子shell
[leon@localhost ~]$ echo $test
[leon@localhost ~]$                                                  #為null值

環境變量:對當前shell進程和子進程有效,對其它shell無效

[leon@localhost ~]$ export test=string                            #定義一個環境變量
[leon@localhost ~]$ echo $test
string
[leon@localhost ~]$ bash
[leon@localhost ~]$ echo $test
string

局部變量:對shell腳本中某段代碼片段有效,通常用于函數本地,通常用local來定義

[leon@localhost tmp]$ cat test.sh                                 
#!/bin/bash                                                           #定義使用哪種shell解析腳本
#    
function test {                                                     #定義一個函數
local a=local                                                        #定義一個局部變量
echo $a
}
test && echo $a
[leon@localhost tmp]$ ./test.sh 
local

位置變量:$0  $1  $2…$n

[leon@localhost tmp]$ sh test1.sh 1
[leon@localhost tmp]$ cat test1.sh 
#!/bin/bash
#
echo $0
echo $1
echo $2
[leon@localhost tmp]$ sh test1.sh string1 string2 string3        #傳遞位置參數
test1.sh
string1
string2

常用的特殊變量:$? $@ $* $# $$

[leon@localhost tmp]$ cat test2.sh 
#!/bin/bash
#
echo $*
echo $@
echo $#
echo $?
echo $$
[leon@localhost tmp]$ sh test2.sh string1 string2 string3 string4
string1 string2 string3 string4
string1 string2 string3 string4
4
0
1650

數組  :是特殊的變量,bash支持一維數組。數組由數組名+索引 組成。

如:a[1] a[2] a[3] … a[N]  a[hello]  a[Number]  a[string] …

2.2 變量的聲明及賦值

1.不能使用系統內置變量

2.以字母,數字,下劃線組成,不能以數字開頭

3.見名知義

[leon@localhost tmp]$ PATH=/tmp
[leon@localhost tmp]$ ls
bash: ls: command not found
[leon@localhost ~]$ 
[leon@localhost ~]$ 1test=test
-bash: 1test=test: command not found

定義整型的變量

[leon@localhost ~]$ declare -i number=23                #使用declare -i定義一個整型變量

定義數組

可以使用declare 定義

[leon@localhost ~]$ declare -a a=(1 2 3 4)            #定義一個數組
[leon@localhost ~]$ echo ${a[@]}
1 2 3 4
[leon@localhost ~]$ b=(1 2 3 4)
[leon@localhost ~]$ echo ${b[@]}
1 2 3 4
[leon@localhost ~]$ declare -A string=([hello]='hello' [day]='sunday')    #定義一個關聯型數組
[leon@localhost ~]$ echo ${string[@]}
sunday hello
[leon@localhost ~]$ logs=(/home/*)            #給變量賦值
[leon@localhost ~]$ echo ${logs[@]}
/home/leon /home/openstack /home/test

三、數組及字符串操作

3.1 數組操作

3.1.1 數組長度

${#ARRAY[*]}

${#ARRAY[@]}

[leon@localhost ~]$ declare -A string=([hello]='hello' [day]='sunday')
[leon@localhost ~]$ echo ${#string[@]} && echo ${#string[*]}
2 2

3.1.2 數組中挑選某些元素

${ARRAY[@]:offset:number}

[leon@localhost ~]$ echo ${string[@]}
sunday hello
[leon@localhost ~]$ echo ${string[@]:1:1}
sunday
[leon@localhost ~]$ echo ${string[@]:1:2}
sunday hello
[leon@localhost ~]$ echo ${string[@]:1}
sunday hello

3.1.3 數組的刪除

unset ARRAY

[leon@localhost ~]$ echo ${logs[@]}
/home/leon /home/openstack /home/test
[leon@localhost ~]$ unset logs[1]        #刪除索引為1的數組
[leon@localhost ~]$ echo ${logs[@]}
/home/leon /home/test
[leon@localhost ~]$ unset logs
[leon@localhost ~]$ echo ${logs[@]}

[leon@localhost ~]$

3.2 字符串操作

3.2.1 字符串取子串

${string:offset:length}  :從第offset個向右取length個字符串

[leon@localhost ~]$ string=a1b2c3d4e5f6
[leon@localhost ~]$ echo ${string}
a1b2c3d4e5f6
[leon@localhost ~]$ echo ${string:1:4}
1b2c

${string: -length}    :從右向左取length個字符串

[leon@localhost ~]$ echo ${string}
a1b2c3d4e5f6
[leon@localhost ~]$ echo ${string: -2}
f6

${string#*word} :在string中存儲字符串上,自左而右,查找第一次出現word,刪除字符開始到此word處的所有內容

[leon@localhost ~]$ string=string-hello-myname-is-hello-over
[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string#*hello}
-myname-is-hello-over

${string##*word} :在string中存儲字符串上,自左而右,查找最后一次出現word,刪除字符開始到此word處的所有內容

[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string#*hello}
-myname-is-hello-over
[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string##*hello}
-over

${string%word*}在string中存儲的字符串上,自右而左,查找第一次出現的word,刪除字符開始到此word處的所有內容

[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string%hello*}
string-hello-myname-is-

${string%%word*}在string中存儲的字符串上,自右而左,查找最后一次出現的word,刪除字符開始到此word處的所有內容

[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string%%hello*}
string-

3.2.2 字符串查找替換

${string/pattern/substi} :替換第一次出現的字符串

[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string/hello/hi}
string-hi-myname-is-hello-over

${sting//pattern/substi} :替換所有出現過的字符串

[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string//hello/hi}
string-hi-myname-is-hi-over
${string/pattern}
[leon@localhost ~]$ echo ${string//hello/hi}
[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string/hello}
string--myname-is-hello-over
${string//pattern}[leon@localhost ~]$ echo $string
string-hello-myname-is-hello-over
[leon@localhost ~]$ echo ${string//hello}
string--myname-is--over
[leon@localhost ~]$

四、流程控制

4.1 選擇分支

4.1.1 條件測試

條件測試中,如果為真,則返回執行狀態為0的值,否則返回執行狀態為非0的值

整型測試:數值之間比較大小     字符型比較

-gt  -lt  -eq  -ge  -le    >   <  ==  !=  >=  <=  -n  -z

常用文件測試

-e    文件存在

[leon@localhost ~]$ [ -e /tmp/xxxxxxx ] 
[leon@localhost ~]$ echo $?
1

-d    文件存在且為目錄

[leon@localhost ~]$ [ -d /tmp ] 
[leon@localhost ~]$ echo $?
0

-f    文件存在且為普通文件

[leon@localhost ~]$ [ -f /tmp ] 
[leon@localhost ~]$ echo $?
1

-r    文件是否具有可讀權限

[leon@localhost ~]$ [  -r /root ]

[leon@localhost ~]$ echo $?

1

-w    文件是否具有可寫權限

[leon@localhost ~]$ [ -w /home/leon ]
[leon@localhost ~]$ echo $?
0

-x    文件是否具有可執行權限

[leon@localhost ~]$ [ -x /home/leon ]
[leon@localhost ~]$ echo $?
0

組合條件測試 :在多個條件間實現邏輯運算

與: [ 條件一 -a 條件二 ]

    條件一 && 條件二

[leon@localhost ~]$ [ -x /home -a -r /root ]
[leon@localhost ~]$ echo $?
1

[leon@localhost ~]$ test -x /home &&  test -r /root
[leon@localhost ~]$ echo $?
1

或: [ 條件一 -o 條件二 ]

    條件一 || 條件二 

[leon@localhost ~]$ [ -x /home -o -r /root ]
[leon@localhost ~]$ echo $?
0

[leon@localhost ~]$ test -x /home ||  test -r /tmp
[leon@localhost ~]$ echo $?
0

非:[ !條件 ]

[leon@localhost ~]$ [ ! -r /home/leon ]
[leon@localhost ~]$ echo $?
1

4.1.2 if選擇分支

語法: if 測試條件1;then

    選擇分支1

   elif 測試條件2;then

    選擇分支2

   ……

   elif 測試條件n;then

    選擇分支n

   else

    分支

   fi

[leon@localhost ~]$ if true ; then echo true ;else  echo false ;fi
true[leon@localhost ~]$ 
[leon@localhost ~]$ if id test1 &>/dev/null ; then echo test1 ;elif id test2 &>/dev/null;then echo test2 ;elif id leon &>/dev/null ;then echo leon ;fi
leon
[leon@localhost ~]$ if [ $? -eq 0 ] ;then echo ture ;else echo false;fi
ture

4.1.3 case選擇分支

語法:case word  in

    pattern1)

    分支1

    ;;

    pattern2)

    分支2

    ;;

    patternN)

     分支N

    ;;

    *)

      分支

    ;;

    esac

[leon@localhost ~]$ case leon in  root) id root ;; leon) echo leon ;; *) echo not this user! ;; esac
leon
[leon@localhost tmp]$ cat testCase.sh 
#!/bin/bsh
#
case $1 in
1)
 echo 1
 ;;
2)
 echo 2
 ;;
3)
 echo 3
 ;;
*)
 echo order
 ;;
esac
[leon@localhost tmp]$ chmod +x testCase.sh 
[leon@localhost tmp]$ sh testCase.sh 
order
[leon@localhost tmp]$ ./testCase.sh 1
1

4.2 循環

4.2.1 for循環

語法1: for i in  list ;do

       list

    done

語法2: for ((表達式一;條件表達式;表達式二));do

       list

    done

[leon@localhost tmp]$ for i in {1..5};do echo $i ;done
1
2
3
4
5
[leon@localhost tmp]$ for ((i=1;i<=5;i++));do echo $i ;done
1
2
3
4
5

4.2.2 while循環

語法1: while 測試條件; do

        循環體

    done
語法2: while read 變量名;do

        循環體

    done < /path/to/somefile

[leon@localhost tmp]$ cat testWhile.sh 
#!/bin/bash
#
declare -i i=1
while [ $i -le 5  ];do        #比較i和5的大小,為真則進入循環,為假則退出循環
echo $i
let i++
done
[leon@localhost tmp]$ sh  testWhile.sh
1
2
3
4
5

[leon@localhost tmp]$ cat testWhile.sh 
#!/bin/bash
#
while read userInfo;do
echo $userInfo
done < /etc/passwd
[leon@localhost tmp]$ sh testWhile.sh 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
......
openstack:x:502:502::/home/openstack:/bin/bash
[leon@localhost tmp]$

 4.2.3 until循環

語法:until 測試條件; do

        循環體

    done

[leon@vm tmp]$ cat testUntil.sh 
#!/bin/bash
#
declare -i i=5
until [ $i -lt 1 ];do        #比較i和1的大小,為假就進入循環,為真則退出循環
echo $i
let i--
done
[leon@vm tmp]$ sh testUntil.sh 
5
4
3
2
1

五、函數及返回值

語法1: function function_name {list}

語法2: function_name () {list}

[leon@vm tmp]$ cat testFunction.sh 
#!/bin/bash
#
function display {        #定義一個名為display的函數
cat << NODE

-------------------
------meau---------
1: install os
2: quit
-------------------
NODE
return 0              #退出函數并返回狀態值0
echo next function_list
}
view() {
display                #調用函數
exit 1                #退出shell并返回狀態值1
}
view
[leon@vm tmp]$ sh testFunction.sh 

-------------------
------meau---------
1: install os
2: quit
-------------------
[leon@vm tmp]$ echo $?
1

六、循環控制

continue : 提前進入下一輪循環

[leon@vm tmp]$ cat testContinue.sh
#/bin/bash
#
for (( i=1;i<=2;i++  )) ;do
echo outside $i
for (( n=1;n<=2;n++ ));do
echo inside $n
continue                            #直接進入下一循環
#	break
echo hello                         #這個echo語句用于沒有將會執行
done
done
[leon@vm tmp]$ sh testContinue.sh
outside 1
inside 1
inside 2
outside 2
inside 1
inside 2

break  :跳出當前循環

[leon@vm tmp]$ cat testContinue.sh
#/bin/bash
#
for (( i=1;i<=2;i++  )) ;do
echo outside $i
for (( n=1;n<=2;n++ ));do
echo inside $n
#	continue
break                    #退出當前循環
echo hello
done
done
[leon@vm tmp]$ sh testContinue.sh
outside 1
inside 1
outside 2
inside 1

七、信號捕捉

信號捕捉:trap 'COMMAND;COMMAND'  SINGNAL

[leon@vm tmp]$ cat testTrap.sh 
#!/bin/bash
#
trap 'echo exit' SIGINT
ping -c 100 www.baidu.com
[leon@vm tmp]$ sh testTrap.sh            #按ctrl+c時,捕捉到信號。
PING www.a.shifen.com (180.97.33.108) 56(84) bytes of data.
64 bytes from 180.97.33.108: icmp_seq=1 ttl=128 time=29.4 ms
64 bytes from 180.97.33.108: icmp_seq=2 ttl=128 time=29.5 ms
^C
--- www.a.shifen.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1278ms
rtt min/avg/max/mdev = 29.489/29.530/29.571/0.041 ms
exit                #退出腳本時執行echo語句輸出

八、總結

shell編程是linux運維人員必須掌握的技能,shell不像其它C、C#、Java等高級編程語言那樣有類和對象,面向對象等概念,但是shell可以有強大的命令支撐。畢竟我們是通過shell來溝通內核,不需要運行在虛擬機上。

原創文章,作者:成吉思汗,如若轉載,請注明出處:http://www.www58058.com/8026

(0)
成吉思汗成吉思汗
上一篇 2015-09-22
下一篇 2015-09-22

相關推薦

  • linux命令格式,獲取幫助及其目錄結構簡要理解

    我們都知道,一臺計算機要是沒通電,和一堆廢鐵沒什么區別。那么,通電開機進入系統后,會進入交互界面,等待用戶操作,人與計算機交互界面有兩種: GUI:圖形用戶接口。如我們平時使用的Windows ?,linux的X window,有KDE和GOME.   CLI:命令行接口,使用的SHELL類型有bash ,csh,tcshell,zshell等。 …

    2017-09-14
  • 【福利貼-招聘】- python運維開發工程師

    職位描述  崗位職責: 1、負責公司CMDB的建設,包括資產管理、dns、工單系統、ngnix自動化、監控等的開發 2、幫助運維團隊和業務團隊提高自動化效率 3、維護和開發持續化集成環境; 4、負責公司運維系統的規劃、選型、部署上線和日常維護管理工作; 5、負責CMDB團隊的建設、管理和人才培養機制…

    Linux干貨 2015-04-03
  • LVM: Logical Volume Manager 邏輯卷管理

      一、LVM介紹         LVM: Logical Volume Manager, Version: 2             …

    Linux干貨 2016-09-19
  • keepalived+nginx部署(單主模型)

    環境準備Centos7系統,后端服務器提供web服務。地址規劃: VS1: 172.18.51.7 VS2:172.17.51.77 RS1:172.18.51.74 RS2:172.18.51.75 VirtualIP:172.18.51.82 拓撲圖: 原理:nginx是高度模塊化的應用程序,其中nginx_proxy模塊即可實現負載均衡,將前端的用戶請…

    Linux干貨 2017-05-17
  • 第四周作業

    1. 復制/etc/skel目錄為/home/tuser1,要求/home/tuser1以及內部文件的屬組和其它用戶均沒有任何訪問權限 cp -r /etc/skel  /home/tuser1 chmod go-rwx /home/tuser1 2. 編輯/etc/group文件,添加組hadoo…

    Linux干貨 2016-12-27
  • openssh及基于ssl的https的配置

    openssh的簡介             OpenSSH 是 SSH 協議的免費開源實現。SSH協議族可以用來進行遠程控制, 或在計算機之間傳送文件。 而實現此功能的傳統方式,如telnet(終端仿真協議)、 rcp ftp、 rlogin、rs…

    Linux干貨 2017-05-30

評論列表(1條)

  • stanley
    stanley 2015-09-22 09:35

    總結的非常不錯,文檔功底很深

欧美性久久久久