1. 程式人生 > >Shell指令碼(介紹,變數,運算,條件判斷,迴圈,函式)

Shell指令碼(介紹,變數,運算,條件判斷,迴圈,函式)

shell是人機互動的翻譯

注意的是,shell和Linux核心合在一起才是Linux。

Shell指令碼命令由兩種工作方式,

一種是互動式,寫一句命令,執行一句命令

一種是批處理,一次執行多個命令,先把命令寫好,然後在執行

 舉個例子:

[[email protected] ~]# vim first.sh


#!/bin/bash
#The first shell script by isea_you
pwd
ls -l

其中#!表示使用哪種shell直譯器來執行指令碼,#表示對這個指令碼進行說明

儲存並退出,之後執行該指令碼,結果如下:

[[email protected]
~]# bash ./first.sh /root 總用量 96 -rw-------. 1 root root 1186 10月 16 22:18 anaconda-ks.cfg -rw-r--r--. 1 root root 59 10月 18 23:49 first.sh -rw-r--r--. 1 root root 38951 10月 16 22:17 install.log -rw-r--r--. 1 root root 8481 10月 16 22:15 install.log.syslog drwxr-xr-x. 2 root root 4096 10月 16 22:24 公共的 drwxr-xr-x. 2 root root 4096 10月 16 22:24 模板 drwxr-xr-x. 2 root root 4096 10月 16 22:24 視訊 drwxr-xr-x. 2 root root 4096 10月 16 22:24 圖片 drwxr-xr-x. 2 root root 4096 10月 16 22:24 文件 drwxr-xr-x. 2 root root 4096 10月 16 22:24 下載 drwxr-xr-x. 2 root root 4096 10月 16 22:24 音樂 drwxr-xr-x. 2 root root 4096 10月 16 22:24 桌面

Shell解析器

檢視Linux下提供的shell直譯器有哪些:

[[email protected] shell]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh

sh的本質也是bash,證明如下:

[[email protected] bin]# ll /bin|grep bash
-rwxr-xr-x. 1 root root 941880 5月  11 2016 bash
lrwxrwxrwx. 1 root root      4 10月 16 22:10 sh -> bash

檢視當前的Linux使用的是哪個直譯器:

[[email protected] bin]# echo $shell

[[email protected] bin]# echo $SHELL
/bin/bash

如何執行指令碼:

1,使用bash + 指令碼路徑(相對路徑或者是絕對路徑)

2,直接執行該指令碼檔案(./ 檔名) 前提是當前該指令碼必須有可執行的許可權。

第一種執行的方式,本質是bash解析器幫你執行指令碼,所以指令碼本身不需要執行許可權;第二種執行指令碼需要自己執行,所以需要執行的許可權。

例子:寫一個指令碼,並執行該指令碼:

[[email protected] shell]# cat helloworld.sh 
#!/bin/bash
#print the helloworld
echo hello world
[[email protected] shell]# 


[[email protected] shell]# sh helloworld.sh 
hello world
[[email protected] shell]# bash helloworld.sh 
hello world
[[email protected] shell]# cd 
[[email protected] ~]# bash /root/shell/helloworld.sh 
hello world
[[email protected] ~]# cd shell/
[[email protected] shell]# ll
總用量 12
-rwxr-xr-x. 1 root root 30 10月 24 09:22 a.sh
-rw-r--r--. 1 root root 43 10月 24 09:03 helloworld_python.sh
-rwxr-xr-x. 1 root root 51 10月 24 09:01 helloworld.sh
[[email protected] shell]# ./helloworld.sh 
hello world
[[email protected] shell]# 

Shell變數

系統變數,直接輸入 set ,可以得到所有的變數,系統變數比如下面的這些;

[[email protected] shell]# echo $HOME
/root
[[email protected] shell]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[[email protected] shell]# echo $SHELL
/bin/bash

使用者自定義變數,需要注意的幾點:

定義變數:變數=值  (等號兩側不能有空格)

獲取該變數的值並輸出: echo $變數

撤銷變數:unset 變數

靜態變數的宣告:readonly 變數,注意不能unset 靜態變數

bash中,所有的型別預設都是字串型別,無法直接進行數值的運算。

[[email protected] shell]# A=1
[[email protected] shell]# echo $A
1
[[email protected] shell]# readonly B=2
[[email protected] shell]# echo $B
2
[[email protected] shell]# B=3
-bash: B: readonly variable

無法進行數值的直接運算
[[email protected] shell]# C=1+2
[[email protected] shell]# echo $C
1+2

如果將一個帶空格的字串賦值給變數:
[[email protected] shell]# D=i love you
-bash: love: command not found

必須加上雙引號,或者是單引號
[[email protected] shell]# D="i love you"
[[email protected] shell]# echo $D
i love you

[[email protected] shell]# D='i love you'
[[email protected] shell]# echo $D
i love you

將變數升級為全域性的變數,這樣的話其他的shell就能夠使用,但是如果我們重新連線一個終端的話,該變數將不會在生效:

[[email protected] shell]# echo $A
1

[[email protected] shell]# cat helloworld.sh 
#!/bin/bash
#print the helloworld
echo hello world
echo $A


[[email protected] shell]# sh helloworld.sh 
hello world

[[email protected] shell]# export A=1
[[email protected] shell]# sh helloworld.sh 
hello world
1
[[email protected] shell]# 

特殊變數:

$n  獲取執行指令碼時候,傳入的引數,n表示第幾個引數

$#  獲取執行指令碼的時候,傳入的所有引數的個數

$*  代表命令列中所有的引數,$*把所有的引數看成一個整體

[email protected]   代表命令列中所有的引數,不過[email protected]把每個引數區分對待

$?   最後一次執行的命令的返回狀態。如果這個變數的值為0,證明上一個命令正確執行;如果這個變數的值為非0(具體是哪個數,由命令自己來決定),則證明上一個命令執行不正確了

[[email protected] ~]# vim a.sh

#!/bin/bash
for i in "$*"
do
        echo $i
done

echo "--------------------------"
for i in $*
do
        echo $i
done

echo "--------------------------"

for i in [email protected]
do
        echo $i
done
echo "--------------------------"

for i in "[email protected]"
do
        echo $i
done


[[email protected] ~]# ./a.sh a b c d
a b c d
--------------------------
a
b
c
d
--------------------------
a
b
c
d
--------------------------
a
b
c
d
[[email protected] ~]# vim a.sh

#!/bin/bash
for i in '$*'
do
        echo $i
done


[[email protected] ~]# ./a.sh a b c d
$*

運算子號

(1)“$((運算式))”或“$[運算式]”

(2)expr  + , - , *,  /,  %    加,減,乘,除,取餘

[[email protected] shell]# A=$[(2+3)*4]
[[email protected] shell]# echo $A
20

[[email protected] ~]# vim a.sh
#!/bin/bash
echo $1 $2 $3
echo $#




[[email protected] ~]# ./a.sh 1 2 3
-bash: ./a.sh: 許可權不夠
[[email protected] ~]# chmod +x a.sh
[[email protected] ~]# ./a.sh 1 2 3 4 5 6
1 2 3
6

條件判斷:

基本語法: [ condition ] 注意condition後面都是有空格的

例子:

[[email protected] shell]# [  ]
[[email protected] shell]# echo $?
127
[[email protected] shell]# [ isea_you ]
[[email protected] shell]# echo $?
0
[[email protected] shell]# 

(1)兩個整數之間比較

= 字串比較

-lt 小於(less than)                  -le 小於等於(less equal)

-eq 等於(equal)                     -gt 大於(greater than)

-ge 大於等於(greater equal)   -ne 不等於(Not equal)

[[email protected] ~]# vim ari.sh

#!/bin/bash
if [ $1 -gt $2 ]
then
        echo "succeess"
else
        echo "fail"
fi


[[email protected] ~]# chmod +x ari.sh 
[[email protected] ~]# ./ari.sh 
succeess
[[email protected] ~]# ./ari.sh 1 2
fail
[[email protected] ~]# ./ari.sh 4 2
succeess

(2)按照檔案許可權進行判斷

-r 有讀的許可權(read)              -w 有寫的許可權(write)

-x 有執行的許可權(execute)

(3)按照檔案型別進行判斷

-f 檔案存在並且是一個常規的檔案(file)

-e 檔案存在(existence)          -d 檔案存在並是一個目錄(directory)

[[email protected] shell]# [ 23 -ge 22 ]
[[email protected] shell]# echo $?
0
[[email protected] shell]# [ -w helloword.sh ]
[[email protected] shell]# echo $?
1
[[email protected] shell]# [ -w helloworld.sh ]
[[email protected] shell]# echo $?
0
[[email protected] shell]# [ -e /root/shell/helloworld.sh ]
[[email protected] shell]# echo $?
0

流程控制:

例子:

if 的後面要有空格。 

[[email protected] shell]# sh if.sh
if.sh: line 2: [: -eq: unary operator expected
if.sh: line 5: [: -eq: unary operator expected
[[email protected] shell]# sh if.sh 1 
isea_you
[[email protected] shell]# sh if.sh 2
ifseayou

for迴圈

[[email protected] shell]# vim for.sh
[[email protected] shell]# sh for.sh
5050

while迴圈

[[email protected] shell]# vim while.sh
[[email protected] shell]# sh while.sh
5050
[[email protected] shell]# vim case.sh
#!/bin/bash
case $1 in
        "1")
                echo 111
        ;;
        "2")
                echo 222
        ;;
        *)
                echo other
        ;;
esac



[[email protected] shell]# chmod +x case.sh
[[email protected] shell]# ./case.sh 
other
[[email protected] shell]# ./case.sh 1
111
[[email protected] shell]# ./case.sh 2
222

Read讀取控制檯輸入

選項:

-p:指定讀取值時的提示符;

-t:指定讀取值時等待的時間(秒)。

引數

       變數:指定讀取值的變數名

[[email protected] shell]# vim read.sh

#!/bin/bash
read -t 7 -p "Enter your name in 7 seconds:" NAME
echo $NAME

[[email protected] shell]# sh read.sh 
Enter your name in 7 seconds:isea_you
isea_you

系統函式

basename基本語法

basename [string / pathname] [suffix]   (功能描述:basename命令會刪掉所有的字首包括最後一個(‘/’)字元,然後將字串顯示出來。

選項:suffix為字尾,如果suffix被指定了,basename會將pathname或string中的suffix去掉。

dirname基本語法

       dirname 檔案絕對路徑   (功能描述:從給定的包含絕對路徑的檔名中去除檔名(非目錄的部分),然後返回剩下的路徑(目錄的部分))

[[email protected] shell]# basename /root/shell/if.sh
if.sh
[[email protected] shell]# dirname /root/shell/if.sh 
/root/shell

自定義函式

[[email protected] shell]# function f1(){
> echo $1 $2
> }
[[email protected] shell]# f1 1 2
1 2

(1)必須在呼叫函式地方之前,先宣告函式,shell指令碼是逐行執行。不會像其它語言一樣先編譯。

(2)函式返回值,只能通過$?系統變數獲得,可以顯示加:return返回,如果不加,將以最後一條命令執行結果,作為返回值。return後跟數值n(0-255)

[[email protected] shell]# vim f1.sh

#!/bin/bash
function f1(){
        echo $1 $2
}
f1 a b

[[email protected] shell]# sh f1.sh
a b

-----------------------------------

[[email protected] shell]# vim f1.sh

#!/bin/bash
f1(){
        echo $1 $2
}
f1 a b

[[email protected] shell]# sh f1.sh
a b

---------------------------------

[[email protected] shell]# vim f1.sh

#!/bin/bash
function f1
{#注意此處的{必須換行
        echo $1 $2
}
f1 a b

[[email protected] shell]# sh f1.sh
a b