Linux(15):shell 編程(2)

shell基礎

什麼是 shell ?

Shell是一個命令解釋器,它的做用是解釋執行用戶輸入的命令及程序等,用戶輸入一條命令, Shell 就解釋執行一條。
這種從鍵盤一輸入命令,就能夠當即獲得迴應的對話方式,被稱之爲交互的方式。

Shell存在於操做系統的最外層,負責直接與用戶對話,把用戶的輸入解釋給操做系統,並處理各類各樣的操做,
系統的輸出結果,輸出到屏幕返回給用戶,當咱們輸入系統用戶名和密碼,登陸到 Linux 後的全部操做都是由Shell 解釋並執行的。

什麼是 shell 腳本?

當命令或程序語句不在命令行下執行,而是經過一個程序文件執行時,該程序就被稱爲 Shell 腳本。
若是在 Shell 腳本里內置了不少條命令、語句及循環控制,而後一次性把這些命令執行完,這種經過文件執行腳本的方式,稱爲非交互的方式。 
Shell 腳本相似於 DOS 系統下的批處理程序。用戶能夠在 Shell 腳本中敲入一系列的命令及命令語句組合。
這些命令、變量和流程控制語句等有機地結合起來就造成了一個 Shell 腳本。


# 示例:清除/var/log下messages日誌文件的Shell腳本(含命令、變量和流程控制語句)
#!/bin/bash

LOG_DIR=/var/log
ROOT_UID=0

# 第一步:必須是 root 用戶才能執行腳本,不然給出提示並終止腳本運行

if [ "$UID" -ne "$ROOT_UID" ]                    # $UID 是系統變量
then
    echo "only root user can run this script"
    exit 1 
fi

# 第二步:成功切換到目錄 /var/log ,不然給出提示並終止腳本運行
cd $LOG_DIR || {                                # || 的做用:前面的命令執行失敗了,則執行後面的操做
    echo "change dir failed"
    exit 1
}

# 第三步:清理日誌 /var/log/message ,清理成功,給出正確提示
cat /dev/null>messages && {                        # && 的做用:前面的操做執行成功了,再執行後面的操做
    echo "Logs cleaned up."
    exit 0
}

# 第四步:清理失敗,給出相應提示
echo "Logs cleaned up failed"
exit 1

Shell腳本在Linux運維工做中地位

Shell腳本語言很擅長處理純文本類型的數據,而Linux系統中幾乎全部的配置文件、日誌文件(如NFS、Rsync、Httpd、Nginx、LVS、MySQL等),以及絕大多數的啓動文件都是純文本類型的文件。天然學好Shell腳本語言,就能夠利用它在Linux系統中發揮巨大的做用。

Shell腳本語言和3P語言對比

Shell腳本語言的優點在於處理偏操做系統底層的業務,例如:Linux系統內部的不少應用,對於一些常見的企業業務,使用Shell開發會更簡單快速,例如:讓軟件一鍵自動化安裝、優化,監控報警腳本,軟件啓動腳本,
日誌分析腳本等,雖然PHP
/Python語言也可以作到,可是,考慮到掌握難度、開發效率、開發習慣等,它們可能就不如用Shell腳本語言流行及有優點了。對於一些常規的業務應用,使用Shell更符合Linux運維簡單、易用、
高效的三大基本原則。 PHP語言: PHP是網頁程序語言,也是腳本語言。是一款更注於Web頁面開發(前端展現)的語言,例如:wordpress、dedecms、discuz等著名開源產品都是用PHP語言開發的。 Perl語言: Perl腳本語言,語法靈活、複雜,缺點是不易讀,團隊協做困難,存世的大量相關程序軟件(好比,xtrabackup熱備工具、MySQL MHA集羣高可用軟件等都有Perl語言的身影)。 Python語言: Python是當下流行的語言,不但能夠用於腳本程序開發,也可實現Web程序開發(例如:CMDB管理系統),還能夠作軟件開發( OpenStack)、遊戲開發、大數據開發、移動端開發。

shell腳本的註釋

#號後面表示註釋

# 多行註釋:
# 方式1:
插入註釋:
按CTL+v(win下面ctrl+q)進入列模式;
按大些「I」進入插入模式,輸入註釋符「#」或者是"//",而後馬上按下ESC(兩下)

取消註釋:
Ctrl + v 進入塊選擇模式,選中你要刪除的行首的註釋符號,注意// 要選中兩個,選好以後按d便可刪除註釋

# 方式2:
把須要註釋的代碼放到 :<<EOF...EOF 中,以下所示:
:<<EOF
echo "hello world"
echo "hello world"
EOF

# 方式2 的原理:冒號在shell裏面也是命令,表示什麼都不作

# 方式3:
把須要註釋的代碼放到 cat >/dev/null<<EOF...EOF 中,以下:
cat >/dev/null<<EOF
echo "hello world"
echo "hello world"
EOF

Shell腳本的執行

# 方式1. bash script name 或 sh script name
這是當腳本文件自己沒有可執行權限(即文件權限屬性x位爲 - 號)時常使用的方法,或者腳本文件開頭沒有指定解釋器時須要使用的方法(推薦)

# 方式2. path/script name 或 ./script name
指在當前路徑下執行腳本(腳本要有執行權限),須要先將腳本文件的權限改成可執行(即文件權限屬性加 x),具體方法爲 chmod +x script name 。而後經過腳本絕對路徑或相對路徑就能夠直接執行腳本了。

# 方式3. source script name 或 . script name

# 方式4. sh <script name 或 cat scripts name|sh

# 示例:關閉開機自啓動的程序
chkconfig --list|grep 3:on|awk '{print "chkconfig",$1,"off"}'|bash        # 非循環的方法


# Shell腳本執行過程及父子Shell知識和互相調用

# 登錄一個命令行時,就至關於開啓了一個 shell
# 示例
[root@m01 scripts]# cat test.sh 
user=`whoami`                            # 運行這個腳本時,`whoami` 會執行,即把 root 賦值給 user 變量
[root@m01 scripts]# sh test.sh             # 此時的 sh test.sh 至關於 新開啓了一個 shell (子shell),即在一開始登錄的shell下新開啓了一個子shell
[root@m01 scripts]# echo $user            # 這個 shell 是你一開始登錄時的 shell    (父shell)
                                        # 一開始登錄的 shell 中找不到 user 這個變量的值
[root@m01 scripts]# source test.sh         # 當 source 執行一個腳本時,這個腳本至關因而在當前 shell 下運行(即一開始登錄的shell),即此時沒有開啓新的shell
[root@m01 scripts]# echo $user 
root                                    # 通過 source test.sh 以後,echo $user 就會有輸出
[root@m01 scripts]# cat call_test.sh    
sh test.sh                                # 在 call_test.sh 中又執行了一個新的子shell
echo $user
[root@m01 scripts]# sh call_test.sh     # sh call_test.sh 執行了一個新的子shell
                                        # call_test.sh 這個子shell 沒法調用 test.sh 這個子shell中的變量(test.sh的shell至關於call_test.sh shell的子shell)
[root@m01 scripts]# cat call_test.sh
source ./test.sh                        # 利用 source 或 . 能讓 test.sh 和 call_test.sh 在同一個shell下面執行腳本
echo $user
[root@m01 scripts]# sh call_test.sh 
root                                    # 利用 source 或 . 就能讓 call_test.sh 中 shell 獲取到 test.sh 的shell 中的內容
[root@m01 scripts]# OLDBOY=oldboy        # 在一開始登錄的shell中定義一個變量 OLDBOY
[root@m01 scripts]# cat call_parent.sh 
echo $OLDBOY                            # 在 call_parent.sh 的 shell 中調用父shell中的變量 OLDBOY
[root@m01 scripts]# sh call_parent.sh 
                                        # 沒法調用 父shell 中的變量
[root@m01 scripts]# source call_parent.sh     # 利用 source 也能讓 子shell調用父shell 中的變量
oldboy
[root@m01 scripts]# 

# 使用 source 或 . 來執行腳本,至關於在同一個shell下面執行腳本,此時變量能夠相互調用;
# bash 或 sh 來執行腳本,會開啓一個新的 shell (一個子shell,父shell調用不了子shell中的變量)

# 父shell和子shell的概念:
在腳本A中運行的腳本B就稱爲腳本A的子shell, A 是 B 的父shell;
父shell和子shell之間默認不能互相調用 

shell執行流程圖:前端

Shell腳本的編程規範和習慣

1. 開頭加腳本解釋器
2. 附帶做者及版權信息
3. 腳本擴展名爲 sh
4. 腳本存放在固定的目錄下
5. 腳本中不用中文
6. 成對的符號一次書寫完成
7. 循環格式一次性輸入完成

shell 變量:

默認狀況下,在bash Shell 中是不會區分變量是什麼類型的,例如:常見的變量類型爲整數、字符串、小數等。
變量可分爲兩類:環境變量(全局變量)和普通變量(局部變量)。環境變量也可稱爲全局變量,能夠在建立他們的 Shell 及其派生出來的任意子進程 Shell 中使用,環境變量又可分爲自定義環境變量和 bash 內置的環境變量。
普通變量也可稱爲局部變量,只能在建立他們的Shell 函數或 Shell 腳本中使用。普通變量通常由開發者在開發腳本程序時建立。 (
1) 環境變量 # 顯示環境變量: 1、echo $變量名字 2、env 3. set # 定義環境變量:(定義變量時 = 兩邊不能有空格) # 3種方法 環境變量儘可能大寫,環境變量全局生效。 #方式1: export OLDBOY=1 # 方式2: OLDGIRL=2 export OLDGIRL # 方式3: declare -x declare -x A=1 # 上面3種方法是臨時定義環境變量,想要永久定義環境變量,可修改 /etc/profile 文件 [root@web01 scripts]# tail -1 /etc/profile export OLDBOY=1 [root@web01 scripts]# . /etc/profile [root@web01 scripts]# echo $OLDBOY 1 # 環境變量取消: unset 環境變量名稱 unset OLDBOY # 環境變量的文件: 全局文件 /etc/profile /etc/bashrc 用戶環境變量文件 ~/.bashrc ~/.bash_profile # 環境變量初始化與對應文件生效順序:(即環境變量文件生效順序的優先級) /etc/bashrc > ~/.bashrc > ~/.bash_profile > /etc/profile # 登陸shell時,優先/etc/profile,而後加載~/.bash_profile ,再次加載~/.bashrc,最後加載/etc/bashrc (越日後的文件,生效的優先級越高) # 建議環境變量放在 /etc/bashrc 中 2)普通變量 當前用戶或者腳本中生效,離開當前用戶或者腳本就會失效。 # 變量名: 規則:字母、數字、下劃線,3者組合,以字母開頭。 要求:見名知意 格式: 1)OldboyAge=1 2)oldboy_age=1 3) oldboyAge=1 ###駝峯語法 # 變量內容: 字符串: 變量名=value # 不加引號。 ## 解析變量或者命令,而後輸出;純數字選擇不加引號。 變量名=’value’ # 加單引號。 ## 所見即所得 變量名=」value」 # 加雙引號。 ## 解析變量或者命令,而後輸出;本身定義字符串變量時可默認選擇雙引號;會把要定義的內容做爲一個總體。 命令變量 變量名=`ls` 變量名=$(ls) # 普通變量總結: 針對變量名: 1)變量名的定義要有必定的命令規範,而且要見名知意 OldboyAge=1 ,推薦使用駝峯語法。 2)變量名僅能使用字母、數字、下劃線中的任意多個字符,而且要字母開頭。 針對變量內容: 3)在腳本中定義普通字符串變量,儘可能把變量的內容用雙引號括起來。 4)單純數字的變量內容能夠不加引號。 5)但願變量的內容原樣輸出需加單引號。 6)但願變量值引用命令並獲取命令的結果就用反引號或 $() 。 針對賦值符號: 7)變量定義使用賦值符號 (=),賦值符號兩端不要有空格。 針對變量輸出: 8)使用或者輸出變量的內容,可用 $變量名,例如 :echo $OldboyAge 。 9)若變量 (db) 後面有其餘字符鏈接的時候,就必須給變量名 加上大括號 {},例如: $db_t 就要改爲 ${db}_t # 特殊位置變量: $0 獲取腳本的名字,若是腳本前面跟着路徑的話,那就獲取路徑加上腳本名字。 [root@m01 scripts]# cat test.sh echo $0 [root@m01 scripts]# pwd /server/scripts [root@m01 scripts]# sh test.sh test.sh [root@m01 ~]# sh /server/scripts/test.sh /server/scripts/test.sh # $0 企業應用: 通常在啓動腳本的結尾會使用$0獲取腳本的路徑和名字給用戶提示用;如 /etc/init.d/crond 中: echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" $1,$2 --- $n $1表示腳本後的第一個參數 $2表示腳本後的第二個參數 ... 超過$9時,要想獲取到後面的參數時,就要加上{},如 ${10} 企業應用: case "$1" in # 啓動腳本的參數 start) rh_status_q && exit 0 $1 ;; stop) $# 表示腳本後面全部參數的總個數 企業應用: [root@web01 scripts]# cat test.sh #!/bin/bash if [ $# -ne 2 ] # 獲取參數的總個數 then echo "Usage:$0 arg1 arg2" exit 1 fi echo ok $* 獲取腳本的全部參數,格式爲: "$1 $2 $3" (即全部參數爲一個總體) $@ 獲取腳本的全部參數,格式爲: "$1" "$2" "$3" (每一個參數都是一個單獨的個體) # 應用場景:當須要接收腳本後面全部參數時,可是又不知道參數個數就用這兩個變量。 區別: [root@m01 test]# cat test.sh #!/bin/bash for arg1 in "$*" do echo $arg1 done echo --------------------- for arg2 in "$@" do echo $arg2 done [root@m01 test]# sh test.sh "I am" neo coder. I am neo coder. --------------------- I am neo coder. # shell進程特殊狀態變量: $? 表示獲取上一個命令的返回值,若是返回值爲0就證實上一個命令執行正確,非0,就證實上一個命令執行失敗的。以下: echo $? $$ 表示獲取當前執行腳本的進程號。以下: [root@m01 test]# cat test2.sh #!/bin/bash echo $$|tee /tmp/a.log # tee 的做用:讓 echo 輸出,同時也讓輸出的結果打印到一個 log中 sleep 100 [root@m01 test]# sh test2.sh & # & 的做用表示後臺進行 [1] 4695 [root@m01 test]# 4695 [root@m01 test]# ps -ef|grep test2.sh root 4695 3595 0 01:55 pts/2 00:00:00 sh test2.sh root 4702 3595 0 01:55 pts/2 00:00:00 grep --color=auto test2.sh [root@m01 test]# cat /tmp/a.log 4695 [root@m01 test]# kill `cat /tmp/a.log` # 經過 $$ 對進程進行管理 $! 表示獲取上一個後臺工做進程的進程號 $_ 表示獲取上一個執行腳本的最後一個參數 # Shell變量子串 ${#parameter} ---> 返回變量 $parameter 內容的長度(按字符),也適用於特殊變量 # 應用:查看字符串的長度 [root@m01 ~]# oldboy="I am oldboy" [root@m01 ~]# echo ${oldboy} I am oldboy [root@m01 ~]# echo $oldboy |wc -L 11 [root@m01 ~]# expr length "$oldboy" 11 [root@m01 ~]# echo $oldboy |awk '{print length}' 11 [root@m01 ~]# echo $oldboy |awk '{print length ($0)}' 11 練習題: I am oldboy I teach linux 打印這些字符串中字符數小於3的單詞。 涉及知識點:取字符串長度,for,if。 [root@m01 ~]# echo ${oldboy:3} m oldboy [root@m01 ~]# echo ${oldboy:2:2} am [root@m01 ~]# echo ${oldboy:3:3} m o [root@m01 ~]# OLDBOY=abcABC123ABCabc [root@m01 ~]# echo ${OLDBOY} abcABC123ABCabc [root@m01 ~]# echo ${OLDBOY#a*C} 123ABCabc [root@m01 ~]# echo ${OLDBOY##a*C} abc [root@m01 ~]# echo ${OLDBOY%a*C} abcABC123ABCabc [root@m01 ~]# echo ${OLDBOY%a*c} abcABC123ABC [root@m01 ~]# echo ${OLDBOY%%a*c} [root@m01 ~]# [root@m01 ~]# OLDBOY="I am oldboy oldboy" [root@m01 ~]# echo ${OLDBOY} I am oldboy oldboy [root@m01 ~]# echo ${OLDBOY/oldboy/oldgirl} I am oldgirl oldboy [root@m01 ~]# echo ${OLDBOY//oldboy/oldgirl} I am oldgirl oldgirl [root@m01 ~]# ${parameter:-word} 表示若是 parameter 變量值爲空或未賦值,就會返回 word 字符串替代變量的值。 [root@m01 ~]# result=${test:-UNSET} [root@m01 ~]# echo $result UNSET [root@m01 ~]# echo $test [root@m01 ~]#

shell變量執行順序:linux

shell特殊變量:web

shell變量子串:shell

 

Bash編程常見運算命令彙總

# 只適合整數運算:
1、(()) 推薦
2、let 次推薦
3、expr
4、$[]
五、declare -i
# 既適合整數,又適合小數運算: 1、bc 2、awk 推薦 示例: ############# 整數 ############### # 一、(()) 推薦 [root@m01 ~]# a=1 [root@m01 ~]# b=2 [root@m01 ~]# a=$b+1 # 此時 $b+1 並不會進行數值上的相加 [root@m01 ~]# echo $a 2+1 [root@m01 ~]# a=$((b+1)) # 把要計算的內容用 (()) 括起來,就能進行數值上的運算 [root@m01 ~]# echo $a 3 [root@m01 ~]# echo $((b+3)) 5 [root@m01 ~]# echo 2**3 2**3 [root@m01 ~]# echo $((2**3)) 8 [root@m01 ~]# echo $((5/3)) 1 [root@m01 ~]# echo $((1+2**3-5/3)) 8 [root@m01 ~]# echo $((1+2**3-5%3)) 7 [root@m01 ~]# ((i++)) # i 自加1,前面不用加 $符號 [root@m01 ~]# echo $i 2 [root@m01 ~]# ((i++)) [root@m01 ~]# echo $i 3 # 二、let 次推薦 [root@m01 ~]# a=2 [root@m01 ~]# i=$a+1 [root@m01 ~]# echo $i 2+1 [root@m01 ~]# let i=$a+1 # let 用來運算 [root@m01 ~]# echo $i 3 # 三、expr用於運算(expr作運算時,運算符號兩邊必須都有空格) [root@m01 ~]# expr 50 / 30 1 [root@m01 ~]# expr 1 + 2 3 [root@m01 ~]# expr 2 \* 3 # expr 在進行乘法時,要先將 * 進行轉義 6 [root@m01 ~]# expr 2 '*' 3 # expr 乘法時,也可給 * 加上引號 6 # 四、$[] [root@m01 ~]# echo $[2+ 3] 5 [root@m01 ~]# echo $[2*2] 4

# 五、declare -i
[root@m01 ~]# declare -i a=3+4
[root@m01 ~]# echo $a
7
############### 小數 ################# # 一、 bc [root@m01 ~]# echo 1+2|bc # 經過 | 給 bc 3 [root@m01 ~]# echo 1.3+2.5|bc # 能進行小數的運算 3.8 [root@m01 ~]# echo 5/3|bc 1 # 二、 awk (推薦使用awk) [root@m01 ~]# echo 2.1 1.4|awk '{print $1-$2}' 0.7 [root@m01 ~]# echo 2.1 1.4|awk '{print $1*$2}' 2.94 [root@m01 ~]# echo 2.1 1.4|awk '{print $1/$2}' 1.5 [root@m01 ~]# echo 5 3|awk '{print $1/$2}' 1.66667

expr實戰案例:

# 一、 判斷一個變量值或字符串是否爲整數
# 在shell編程裏,因爲函數庫不多,所以在判斷字符串是否爲整數時就不是很容易。判斷一個字符串是否爲整數的方法以下:
# 實現原理:利用以 expr 作計算時必須是整數的規則,把一個變量或字符串和一個已知的整數(非0)相加,看命令返回值是否爲0,若是爲0,
# 就認爲作加法的變量是整數,反之則不爲整數

# 示例以下:
[root@m01 scripts]# cat judge_int.sh
#!/bin/bash

expr 2 + $1 &>/dev/null   # $1 表示接收到的第一個參數; &>/dev/null 表示結果丟到空裏面
if [ $? -eq 0 ]
then
    echo "$1 is integer"
else
    echo "$1 is not integer"
fi
[root@m01 scripts]# sh judge_int.sh 123
123 is integer
[root@m01 scripts]# sh judge_int.sh neo
neo is not integer
[root@m01 scripts]#


# 二、 判斷文件擴展名是否符合要求
# 補充知識點: expr "變量" : "ReExp"    # 可用於匹配; : 兩邊都要有空格

# 示例以下:
[root@m01 scripts]# cat judge_suffix.sh 
#!/bin/bash

expr "$1" : ".*\.txt" &>/dev/null   # 匹配文件文件;若匹配則返回值爲0,反之則爲非0
if [ $? -eq 0 ]
then
    echo "$1 is text file"
else
    echo "$1 is not text file"
fi
[root@m01 scripts]# bash judge_suffix.sh abc.txt
abc.txt is text file
[root@m01 scripts]# bash judge_suffix.sh abc.mp3
abc.mp3 is not text file
[root@m01 scripts]#

# 三、 expr length "字符串"  ---> 也可用於獲取字符串的長度
[root@m01 ~]# OLDBOY="I am oldboy"
[root@m01 ~]# expr length "$OLDBOY"
11
[root@m01 ~]# 

bash內置核心命令read

# 變量的賦值:
# 1. 定義法: 如 a=1
# 2. 傳參法: 如 $一、$2 等
# 3. read讀入: 即讀取用戶輸入
        -p  提示
        -t  等待用戶輸入的時間

# read 示例:
[root@m01 ~]# read -t 5 -p "pls input a integer:"    # -t 表示超時時間
...
[root@m01 ~]# read -t 5 -p "pls input a integer:" OLDBOY  # 用戶輸入的變量賦值給了 OLDBOY;OLDBOY前面必定要有空格,並且 OLDBOY前不能有 $
pls input a integer:1
[root@m01 ~]# echo $OLDBOY 
1
[root@m01 ~]# 

# read讀入的做用: 和用戶交互
# 示例以下:
[root@m01 scripts]# cat read_cal.sh
#!/bin/bash

#read -t 30 -p "pls input the value of a:" a
#read -t 30 -p "pls input the value of b:" b

read -p "pls input two integers:" a b

echo "a+b=$((a+b))"
echo "a-b=$((a-b))"
echo "a*b=$((a*b))"
echo "a/b=$((a/b))"
echo "a**b=$((a**b))"
echo "a%b=$((a%b))"

[root@m01 scripts]# bash read_cal.sh 
pls input two integers:4 6
a+b=10
a-b=-2
a*b=24
a/b=0
a**b=4096
a%b=4
[root@m01 scripts]# 

# read的企業應用:
[root@m01 scripts]# cat read_pratice.sh
#!/bin/bash

cat <<EOF                # 輸入追加
    1. install lamp        # 菜單
    2. install lnmp
    3. exit
EOF
[root@m01 scripts]# sh read_pratice.sh 
    1. install lamp
    2. install lnmp
    3. exit
[root@m01 scripts]# cat read_pratice.sh
#!/bin/bash

cat <<EOF
    1. install lamp
    2. install lnmp
    3. exit
EOF

read -p "pls input an integer from above:" num

# 1. 判斷是否爲數字
expr 2 + $num &>/dev/null
if [ $? -ne 0 ]
then
    echo "Usage:$0 {1|2|3}"
    exit 1
fi

# 判斷執行處理
if [ $num -eq 1 ]
then
    echo "install lamp..."
elif [ $num -eq 2 ]
then
    echo "install lnmp..."
elif [ $num -eq 3 ]
then
    echo "bye."
    exit          # 退出腳本
else
    echo "Usage:$0 {1|2|3}"
    exit 1
fi
[root@m01 scripts]# sh read_pratice.sh
    1. install lamp
    2. install lnmp
    3. exit
pls input an integer from above:1
install lamp...
[root@m01 scripts]# sh read_pratice.sh
    1. install lamp
    2. install lnmp
    3. exit
pls input an integer from above:3
bye.
[root@m01 scripts]# sh read_pratice.sh
    1. install lamp
    2. install lnmp
    3. exit
pls input an integer from above:4
Usage:read_pratice.sh {1|2|3}
[root@m01 scripts]# sh read_pratice.sh
    1. install lamp
    2. install lnmp
    3. exit
pls input an integer from above:abmvdo
Usage:read_pratice.sh {1|2|3}
[root@m01 scripts]# 

條件表達式

一般,在bash的各類條件結構和流程控制結構中都要進行各類測試,而後根據測試結果執行不一樣的操做,有時也會與if等條件語句相結合,
來完成測試判斷,減小程序運行的錯誤。
執行測試條件表達式後一般會返回「真」或「假」,就像執行命令後的返回值爲0表示真,非0表示假同樣

語法1: test 測試表達式
語法2: [ 測試表達式 ]    #兩端有空格
語法3:[[ 測試表達式 ]]  #兩端有空格
語法4:((測試表達式))    #不須要空格

語法5:(命令表達式) 
語法6:`命令表達式`


# 條件表達式的編程語法:
[ 測試表達式 ] && 命令1
# 若是前面表達式成功,那麼就執行後面命令。

[ 測試表達式 ] || 命令1
# 若是前面表達式失敗,那麼就執行後面命令。

[ 測試表達式 ] && {
命令1
命令2
命令3
}
# 若是前面表達式成功,那麼就執行後面命令。

[ 測試表達式 ] && 命令1 || 命令2
# 若是前面表達式成功,那麼就執行命令1,不然執行命令2(至關於一個if...else...語句),以下:
if [ 測試表達式 ]
then 
    命令1
else
    命令2
fi


[ 測試表達式 ] && {
命令1
命令2
}||{
命令3
命令4
}
# 若是前面表達式成功,那麼就執行命令1,2,不然執行命令3,4。

# 示例以下:
[root@m01 ~]# [ -d /etc/hosts ] && echo "is directory" || echo "not directory"        # -d  --> 是否存在且爲目錄
not directory
[root@m01 ~]# [ -d /etc ] && echo "is directory" || echo "not directory"
is directory
[root@m01 ~]# [ -e /etc/host ] && echo "exist" || echo "not exist"                    # -e  -->  是否存在 
not exist
[root@m01 ~]# [ -e /etc/hosts ] && echo "exist" || echo "not exist"
exist
[root@m01 ~]# [ -r /etc/hosts ] && echo readable || echo "not readable"                # -r  --> 是否可讀
readable
[root@m01 ~]# [ -x /etc/hosts ] && echo "executable" || echo "not executalbe"        # -x  --> 是否可執行; 是否可讀、可執行等的依據是看文件屬性的
not executalbe
[root@m01 ~]# [ -s /etc/hosts ] && echo "file size not 0" || echo "file size is 0"    # -s  --> 文件大小不爲0,則返回真(返回值爲0)
file size not 0

文件測試表達式:
爲何須要文件測試表達式?
操做一個對象,就要看對象條件是否知足,不然不要操做。
1、常見功能
2、實踐
3、企業應用:啓動腳本中的應用。


# 字符串測試表達式:
[ -n "字符串" ]                    # 字符串長度[不]爲0,表達式爲真。 not zero。
[ -z "字符串" ]                    # 字符串長度爲0,表達式爲真。 zero。
[ "字符串1" == "字符串2" ]      # 兩個字符串相同則爲真。
[ "字符串1" !== "字符串2" ]     # 兩個字符串不相同則爲真。


注意:
1、字符串要用雙引號
2、等號能夠用一個或者兩個。
三、=號兩端必需要有空格。

# 示例以下:
[root@m01 ~]# [ -n "neo" ] && echo "length not zero" || echo "length zero"
length not zero
[root@m01 ~]# [ -z "neo" ] && echo "length is zero" || echo "length is not zero"
length is not zero
[root@m01 ~]# char="neo"
[root@m01 ~]# [ -n "$char" ] && echo "length not zero" || echo "length zero"
length not zero
[root@m01 ~]# unset char
[root@m01 ~]# [ -n "$char" ] && echo "length not zero" || echo "length zero"
length zero
[root@m01 ~]# 


# 應用示例:
[root@m01 scripts]# cat read_cal.sh 
#!/bin/bash

read -p "pls input two integers:" a b

# 1. 先判斷是否輸入了兩個參數
[ -z "$b" ] &&{     # 若是變量b沒有值,則輸入的變量數量必定是不夠2個
    echo "pls input two args"
    exit 1
}

# 判斷輸入的變量是否爲數字
expr $a + $b + 1 &>/dev/null
if [ $? -ne 0 ]
then 
    echo "Usage:$0 arg1 and arg2 must be integers"
    exit 1
fi

# 3. 進行運算
echo "a+b=$((a+b))"
echo "a-b=$((a-b))"
echo "a*b=$((a*b))"
echo "a/b=$((a/b))"
echo "a**b=$((a**b))"
echo "a%b=$((a%b))"
[root@m01 scripts]# bash read_cal.sh
pls input two integers:
pls input two args
[root@m01 scripts]# bash read_cal.sh
pls input two integers:1
pls input two args
[root@m01 scripts]# bash read_cal.sh
pls input two integers:ab 1      
Usage:read_cal.sh arg1 and arg2 must be integers
[root@m01 scripts]# bash read_cal.sh
pls input two integers:2 3
a+b=5
a-b=-1
a*b=6
a/b=0
a**b=8
a%b=2


# 整數測試表達式:
# 示例以下:
[root@m01 scripts]# [ 1 -eq 1 ] && echo "equal" || echo "not equal"
equal
[root@m01 scripts]# [[ 1 > 2 ]] && echo "greater than" || echo "less than"
less than
[root@m01 scripts]# (( 3>2 )) && echo "greater than" || echo "less than"
greater than
[root@m01 scripts]# [[ 1 -gt 2 ]] && echo "greater than" || echo "less than"
less than

# 整數表達式的應用:
# 使用 read 的交互式方式,來比較兩個整數的大小
# 分析以下:
1、2個數
2、整數
3、比較大小
    大於
    等於
    小於

[root@m01 scripts]# cat compare_int.sh
#!/bin/bash
read -p "pls input two integers:" a b

# 1. 必須至少是兩個參數
[ -z "$b" ] &&{
    echo "pls input at least two integers"
    exit 1
}

# 2. 兩個參數得是整數
expr $a + $b + 1 &>/dev/null
if [ $? -ne 0 ]
then 
    echo "two args must be integers"
    exit 2
fi

# 3. 比較大小
[ $a -gt $b ] && {
    echo "$a > $b"
    exit 0
}
[ $a -eq $b ] &&{
    echo "$a == $b"
    exit 0
}
#[ $a -lt $b ] &&{
#    echo "$a < $b"
#    exit 0
#}

echo "$a < $b"
[root@m01 scripts]# bash compare_int.sh
pls input two integers:a
pls input at least two integers
[root@m01 scripts]# bash compare_int.sh
pls input two integers:1 b
two args must be integers
[root@m01 scripts]# bash compare_int.sh
pls input two integers:1 5
1 < 5
[root@m01 scripts]#


# 邏輯測試表達式:
# 示例以下:
[root@m01 scripts]# [ 1 -eq 2 -a -f /etc/hosts ] && echo "all are true" || echo "not all are true"        # -a 鏈接兩個測試條件
not all are true
[root@m01 scripts]# [ 1 -eq 2 -o -f /etc/hosts ] && echo "at least one is true" || echo  "all are false"
at least one is true
[root@m01 scripts]# [ ! 1 -eq 2 ] && echo 1 || echo 0        # ! ---> 取反
1
[root@m01 scripts]# 

文件測試表達式的常見功能說明:編程

字符串測試表達式的常見功能說明:bash

整數測試表達式知識:less

邏輯測試表達式:運維

不一樣符號測試表達式[ ] 、 [[ ]] 、 (( ))、test的區別:wordpress

相關文章
相關標籤/搜索