Linux運維:Shell腳本(2)

系列筆記傳送門:linux

Shell變量數值計算

shell中的算術運算符
圖片描述web

shell中的運算命令
算術運算符經常使用於運算命令,shell中運算命令有如下幾種:
圖片描述shell

示例1,(())命令實踐
雙小括號的做用是進行數值運算與數值的比較,經常使用。編程

[root@moli_linux1 shell_test] echo $((1+1)) #計算1+1後輸出
2
[root@moli_linux1 shell_test] echo $((9-3))
6
[root@moli_linux1 shell_test] ((i=5))
[root@moli_linux1 shell_test] echo $((i+=1)) #獲取i值,計算i+1,把i+1從新賦給i,輸出i
6
[root@moli_linux1 shell_test] echo $i
6

[root@moli_linux1 shell_test] ((a=1+2**3-4%3))
#<==表達式運算後將結果賦值給變量a,先乘除後加減
[root@moli_linux1 shell_test] echo $((1+2**3-4%3))
#<==這裏直接將運算表達式進行運算並將結果輸出,輸出要加上$符號
8
[root@moli_linux1 shell_test] b=$((1+2**3-4%3))
#<==這裏直接將運算表達式進行運算並將結果輸出,輸出結果賦值給變量b
[root@moli_linux1 shell_test]# echo $b
8
[root@moli_linux1 shell_test] a=$((100*(100+1)/2))
#<==利用公式計算1+2+3....100
[root@moli_linux1 shell_test] echo $a
5050

示例2,用(())命令進行比較vim

[root@moli_linux1 shell_test] echo $((3>6)) 
#<==3>6是不成立的,所以輸出0。表示比較時,1爲真,0爲假
0
[root@moli_linux1 shell_test] echo $((3>1))
#<==3>1是成立的,所以輸出1.
1
[root@moli_linux1 shell_test] echo $((3==3))
#<==3=3是成立的,所以輸出1
1

注意:上面提到的數字和變量必須是整型的,不能是浮點型或字符串。下面的bc和awk命令能夠用於進行浮點數運算。segmentfault

[root@moli_linux1 ~] echo $((a=1.0+2.5))
-bash: a=1.0+2.5: 語法錯誤: 無效的算術運算符 (錯誤符號是 ".0+2.5")
[root@moli_linux1 ~]#

示例3,有關++,--的運算bash

[root@moli_linux1 shell_test] a=10
[root@moli_linux1 shell_test] echo $((a++))
變量a在運算符++以前,輸出整個表達式時會輸出a的值,再進行表達式的自增
10
[root@moli_linux1 shell_test] echo $a
此時輸出a變量的值,是自增後的值,即爲11
11
[root@moli_linux1 shell_test] echo $((a--))
11
[root@moli_linux1 shell_test] echo $a
10
[root@moli_linux1 shell_test] echo $((++a))
變量a在運算符++以後,輸出整個表達式時會先輸出整個表達式自增的值,即11
11
[root@moli_linux1 shell_test] echo $a
11
[root@moli_linux1 shell_test] echo $((--a))
10
[root@moli_linux1 shell_test] echo $a
10

變量在++.--運算符以前,輸出表達式的值爲變量自身,再進行表達式的自增或自減;變量在++.--運算符以後,會先進行表達式的自增或自減,再輸出表達式的值。運維

let運算命令
let運算命令的語法格式爲:let 賦值表達式
let賦值表達式至關於」((賦值表達式))「測試

[root@moli_linux1 shell_test] i=5
[root@moli_linux1 shell_test] let i=i+1
[root@moli_linux1 shell_test] echo $i
6

expr運算命令
語法:expr 表達式spa

[root@moli_linux1 shell_test] expr 2 + 2
4
[root@moli_linux1 shell_test] expr 2 - 2
0
[root@moli_linux1 shell_test] expr 2 * 2
expr: 語法錯誤
[root@moli_linux1 shell_test] expr 2 \* 2
4
[root@moli_linux1 shell_test] expr 2 / 2
1

注意:使用expr時:

  • 運算符及用於計算的數字左右至少有一個空格,不然會報錯
  • 使用乘號時,必須使用反斜線屏蔽其特定含義,由於shell可能會誤解星號的含義

expr在Shell中可配合變量進行計算,但須要用反引號將計算表達式括起來

[root@moli_linux1 shell_test] i=5
[root@moli_linux1 shell_test] i=` expr $i + 6 `
此處反引號括起來的表達式,變量和數字符號兩邊都要有空格
[root@moli_linux1 shell_test] echo $i
11

Shell腳本中常見的需求

一、判斷一個未知的變量是否是整數
原理: 利用expr作計算時變量或字符串必須是整數的規則,把一個變量和一個整數(非零)相加。看命令的返回值是否爲0。若是爲0,就認爲與整數相加的變量是整數,若是不是0,就不是整數

[root@moli_linux1 shell_test] i=5
#此時的i是整數,數字5
[root@moli_linux1 shell_test] expr $i + 6 &>/dev/null 
#把i與一個整數相加,&>/dev/null 表示不保留任何輸出
[root@moli_linux1 shell_test] echo $?
0
#返回0說明i是整數
[root@moli_linux1 shell_test] i=moli
[root@moli_linux1 shell_test] expr $i + 6 &>/dev/null 
[root@moli_linux1 shell_test] echo $?
2
#返回1說明i不是是整數

二、判斷傳參是否是整數

[root@moli_linux1 shell_test] cat t3.sh 
#!/bin/bash
expr $1 + 1 >/dev/null 2>&1
[ $? -eq 0 ] &&echo int||echo chars
#這是一個條件表達式語法,返回值爲0則輸出int,不然輸出chars
[root@moli_linux1 shell_test] sh t3.sh 1
int
[root@moli_linux1 shell_test] sh t3.sh a
chars

三、編寫shell腳本,查找一段語句中字符數小於6的單詞
思路,須要知道字符串長度的計算方法,利用for循環。
字符串長度能夠利用expr命令得出,如
幾種計算字符串的方法

[root@moli_linux1 ~] char="i am a student"
[root@moli_linux1 ~] expr length "$char"
14
[root@moli_linux1 ~] echo ${#char}
14
[root@moli_linux1 ~] echo ${char} | wc -L
14
[root@moli_linux1 ~] echo ${char} | awk '{print length($0)}'
14

知道怎麼計算字符串長度的方法,就能夠利用計算出來的長度和整數作比較就能夠得出結果了,例如判斷下面這條語句。(有關for循環,if判斷稍後再講)
i am oldboy linux welcome to our training

[root@moli_linux1 shell_test] cat wordLength.sh 
#!/bin/bash
for n in i am oldboy welcome to our training
do
  if [ `expr length $n` -le 6 ]
    then
      echo $n
  fi
done
[root@moli_linux1 shell_test] sh wordLength.sh 
i
am
oldboy
to
our

四、基於Shell變量輸出read命令的運算實踐

Shell變量除了能夠直接賦值或腳本傳參外,還可使用read命令從標準輸入中得到。
語法格式:read [參數] [變量名]
經常使用參數:

  • -p prompt : 設置提示信息
  • -t timeout:設置輸入等待的時間,單位默認爲秒

實現read命令的基本讀入功能

[root@moli_linux1 ~] read -t 10 -p "Please input a num:" num #做爲接受read的變量,不應帶$符號
#讀入一個輸入,賦值給num變量,注意,num變量前須要有空格
Please input a num:10 #輸入10,把數字10賦值給num變量
[root@moli_linux1 ~] echo $num
10
[root@moli_linux1 ~] read -t 10 -p "Please input two num:" a1 a2
#讀入兩個輸入,注意要以空格隔開,分別賦值給a1 a2變量,a1變量先後都要有空格
Please input two num:10 20
[root@moli_linux1 ~] echo $a1 $a2
10 20
[root@moli_linux1 ~] read a3 a4
30 40
[root@moli_linux1 ~] echo $a3
30
[root@moli_linux1 ~] echo $a4
40

read命令小實踐

[root@moli_linux1 shell_test] cat t2_read_change.sh
#!/bin/bash
#no.1
read -t 10 -p "Pleasa input two int number:" a b
#經過read命令讀入兩個值,賦給變量a和變量b
[ ${#a} -le 0 ]&&{
#利用條件表達式,根據變量值的長度是否小於1,來肯定第一個數是否爲空
    echo "The first number is null."
    exit 1
}
[ ${#b} -le 0 ]&&{
#利用條件表達式,根據變量值的長度是否小於1,來肯定第二個數是否爲空
    echo "The second number is null."
    exit 2
}
#no.2 判斷傳參是不是整數
expr $a + 1 &>/dev/null
RETVAL_A=$? 
expr $b + 1 &>/dev/null
RETVAL_B=$?
#若是A和B中有一個不是整數,那麼就打印提示並退出。
if [ $RETVAL_A -ne 0 -o $RETVAL_B -ne 0 ];then
    echo "one of the num is not num,please input again."
    exit 3
fi
#no.3
echo "a+b=$(($a+$b))"
echo "a-b=$(($a-$b))"
echo "a*b=$(($a*$b))"
echo "a/b=$(($a/$b))"

shell的條件測試與比較

在bash中各類條件結構和流程控制結構中都要進行各類測試,根據測試結果執行不一樣的操做
執行條件測試表達式後一般會返回真或假。
在bash編程裏,條件測試經常使用的語法有四種,

條件測試語法 說明
test <表達式> 利用test命令進行條件測試表達式的方法。test命令和表達式之間至少有一個空格。
[ <表達式> ] 這是最經常使用的條件測試表達式。經過[ ]來測試括號內的表達式的方法。[ ]左右邊界至少有一個空格
[[ <表達式> ]] 和[]相似,比較不經常使用,可是它可使用通配符等進行模式匹配,一般[[ ]]左右邊界至少有一個空格
((<表達式>)) 利用雙小括號,兩端不須要有空格,經常使用於if裏的計算。

注意:&&,||,<,>等操做符能夠應用在[[ ]]中,但不能應用在[ ]中,在[ ]中通常使用 -a,-o,-gt等。

文件測試表達式
圖片描述

test條件測試表達式實踐
test命令的語法是:test <測試表達式>
對於下面的命令,

test -f file && echo true || echo false

該語句表示若是文件file存在,就輸出true,不然輸出false。-f參數是文件測試表達式之一,用於測試文件是否爲普通文件。

test表達式也能夠只用一半邏輯,&& 或者 ||,如:

test -f file && echo true #若是表達式成立就輸出true
test -f file || echo false #若是表達式不成立就輸出flase

test中 -選項用來測試字符串長度,若是爲0則表達式成立,不然不成立

[root@moli_linux1 ~] test -z "study" && echo 1 || echo 0
0 #由於study字符串長度不是0,所以輸出0

[ ]條件測試表達式實踐
[ ]條件測試表達式的語法: [ <測試表達式> ]
對於下面語句:

[ -f /tmp/test.txt ] && echo 1 || echo 0

若是/tmp/下有test.txt文件存在,則輸出1.不然輸出0.

文件測試表達式示例
普通文件測試文件類型

[root@moli_linux1 shelltest] touch oldboy #建立普通文件oldboy
[root@moli_linux1 shelltest] ll oldboy 
-rw-r--r-- 1 root root 0 1月  23 18:32 oldboy
[root@moli_linux1 shelltest] [ -f oldboy ] && echo 1 || echo 0
#文件存在,條件爲真,輸出1
1

目錄文件(測試文件類型)

[root@moli_linux1 shelltest] mkdir oldgirl #建立目錄文件oldgirl
[root@moli_linux1 shelltest] [ -f oldgirl ] && echo 1 || echo 0
#輸出爲0,說明文件oldgirl不是普通文件,oldgirl是目錄的確不是普通文件
0
[root@moli_linux1 shelltest] [ -e oldgirl ] && echo 1 || echo 0
1  #輸出爲1,證實文件oldgirl存在,無論oldfirl是目錄仍是普通文件
[root@moli_linux1 shelltest] [ -d oldgirl ] && echo 1 || echo 0
1 #輸出爲1,證實oldgirl是目錄
[root@moli_linux1 shelltest] [ -d oldboy ] && echo 1 || echo 0
0#輸出爲0,證實oldboy不是目錄

字符串測試表達式
字符串測試操做符的做用:比較兩個字符串是否相同,測試字符串的長度是否爲零,字符串是否爲null等。
圖片描述
示例:

[root@moli_linux1 shell_test] [ -n "abc" ] && echo 1 || echo 0
1 #字符串abc的長度不爲0,表達式爲真,輸出1

[root@moli_linux1 shell_test] [ -z "abc" ] && echo 1 || echo 0
0 #字符串abc的長度不爲0,表達式爲假,輸出0

[root@moli_linux1 shell_test] test -n "abc" && echo 1
1 #使用test等同於[]

[root@moli_linux1 shell_test] char=abc
[root@moli_linux1 shell_test] test -n "$char" && echo 1
1 #使用變量時要注意使用雙引號    
[root@moli_linux1 shell_test] [ -z "$char" ] && echo 1 || echo 0
0

[root@moli_linux1 shell_test] char1=abc
[root@moli_linux1 shell_test] char2=abc
[root@moli_linux1 shell_test] char3=moli
[root@moli_linux1 shell_test] [ "$char1" = "$char2" ] && echo 1 || echo 0
1  #變量char1等於char2,表達式爲真,輸出1

[root@moli_linux1 shell_test] [ "$char1" = "$char3" ] && echo 1 || echo 0
0 #變量char1不等於char2,表達式爲假,輸出0

[root@moli_linux1 shell_test] [ "$char1" != "$char3" ] && echo 1 || echo 0
1 #變量char1不等於char3,表達式爲真,輸出1

整數二元比較操做符
圖片描述
示例:

[root@moli_linux1 ~]# a1=98
[root@moli_linux1 ~]# a2=99
[root@moli_linux1 ~]# [ $a1 -eq $a2 ] && echo 1 || echo 0 #判斷a1和a2是否相等
0
[root@moli_linux1 ~]# [ $a1 -gt $a2 ] && echo 1 || echo 0#判斷a1是否大於a2
0
[root@moli_linux1 ~]# [ $a1 -lt $a2 ] && echo 1 || echo 0#判斷a1是否小於a2
1
[root@moli_linux1 ~]# [ $a1 -ne $a2 ] && echo 1 || echo 0#判斷a1和a2是否不相等
1

邏輯操做符
圖片描述
示例:

[root@moli_linux1 shelltest]# [ -f oldboy.txt -o -f oldgirl.txt ] && echo 1
1
[root@moli_linux1 shelltest]# [ -f oldboy.txt -a -f oldgirl.txt ] && echo 1
1
[root@moli_linux1 shelltest]# [ -f oldboy.txt -a -f younggirl.txt ] || echo 1
1
[root@moli_linux1 shelltest]# [ -f oldboy.txt -o -f younggirl.txt ] && echo 1 || echo 0
1

-o規則:
當左邊爲真,右邊爲真,結果爲真
當左邊爲真,右邊爲假,結果爲真
當左邊爲假,右邊爲真,結果爲真
當左邊爲假,右邊爲假,結果爲假
-a規則:
當左邊爲真,右邊爲真,結果爲真
當左邊爲真,右邊爲假,結果爲假
當左邊爲假,右邊爲真,結果爲假
當左邊爲假,右邊爲假,結果爲假

總結
圖片描述

條件表達式和測試表達式的實踐腳本

示例1
經過命令行傳入字符或數字,判斷傳入的字符或數字,執行相應的操做。

[root@moli_linux1 script]# cat test6.sh 
#!/bin/bash
read -p "pls input a char:" var #讀取用戶輸入賦值給var變量
[ "$var" == "1" ] &&{ #條件判斷,看變量值是否爲1
    echo 1
    exit 0
}
[ "$var" == "2" ] &&{ #條件判斷,看變量值是否爲2
    echo 2    
    exit 0
}
[ "$var" != "2" -a "$var" != "1" ] &&{ #若是不等於1或者2,就打印錯誤提示並退出
    echo error
    exit 0
}

示例2
打印選擇菜單,安裝選擇項一鍵安裝不一樣的web服務。

[root@moli_linux1 script]# mkdir -p /root/server/script/lamp.sh
[root@moli_linux1 script]# mkdir -p /root/server/script/lnmp.sh
[root@moli_linux1 script]# echo "echo the lamp is installed" > lamp.sh
[root@moli_linux1 script]# echo "echo the lnmp is installed" > lnmp.sh
[root@moli_linux1 script]# vim menu.sh

#!/bin/bash
path=/root/server/script
[ ! -d "$path" ] && mkdir -p $path
#!/bin/bash
path=/root/server/script
[ ! -d "$path" ] && mkdir -p $path

#menu
cat <<END
    1.[install lamp]
    2.[install lnmp]
    3.[exit]
    pls input the num you want:
END
read num
expr $num + 1 &>/dev/null
[ $? -ne 0 ] && {
    echo "the num you input must be {1|2|3}"
    exit 1
}
[ $num -eq 1 ] &&{
    echo "starint installing lamp"
    sleep 2;
    [ -x "$path/lamp.sh" ]||{
        echo "$path/lamp.sh does not exit or can nor be exec"
        exit 1
    }
    $path/lamp.sh
    exit $?
}
[ $num -eq 2 ] &&{
    echo "starint installing lnmp"
    sleep 2;
    [ -x "$path/lnmp.sh" ]||{
        echo "$path/lnmp.sh does not exit or can nor be exec"
        exit 1
    }
    $path/lnmp.sh
    exit $?
}
[ $num -eq 3 ] &&{
    echo bye
    exit 3
}
[[ ! $num =~ [1-3] ]] &&{ #<==[[]]
    echo "the num you input must be {1|2|3}"
    echo "Input Error"
    exit 4
}
相關文章
相關標籤/搜索