Shell編程之算數、條件測試read詳解二(待續...)

一、shell腳本編程
Shell和shell腳本的區別
    shell就是一個命令行解釋器,它的作用就是遵循一定的語法將輸入的命令加以解釋並傳給系統。它爲用戶提供了一個向Linux發送請求以便運行程序的接口系統級程序,用戶可以用Shell來啓動、掛起、停止甚至是編寫一些程序。Shell本身是一個用C語言編寫的程序,他是用戶使用Linux的橋樑。

        shell即是一種命令語言,優勢一種程序設計語言(就是我們所說的shell腳本)。作爲命令語言,它互動德解釋和執行用戶輸入的命令;作爲程序命令語言它定義了各種變量和參數,並提供了許多在高階語言中才具有的控制結構,包括循環和分支。


  (1)bash中的算術運算

        操作符:+, -, *, /, %(取餘),

            +=, -=,*=, /=, %=

       declare

            -i:整型變量

            -x:環境變量,類似於export

        let varName='算數表達式'

        varName=$[算術表達式]

        varName=$((算術表達式))

        varName=`expr $num1 + $num2`

示例:

(1)

# num1=5
# num2=6
# let sum="$num1*$num2"
# echo $sum
30

# sum=$[num2 - num1]
# echo $sum
1

# sum=`expr $num1 + $num2`
# echo $sum
11

# num1=11
# num2=5
# sum=$((num1/num2))
# echo $sum
2
注意:如果計算結果中存在小數,將會被圓整;

# num1=11
# num2=2
# sum=$[num1%num2]
# echo $sum
1

#a=40
#a=$[a+=2]
#echo $a
42 
自加並賦值給自身

# a=$[a-=2]
# echo $a
40
自減並賦值給自身

#a=40
# a=$[a*=2]
# echo $a
80
乘等並賦值給自身
.....

(2)計算100以內所有整數之和;
#!/bin/bash
#
declare -i sum=0
for i in {1..100}; do
    let sum=$[$sum+$i]
done
echo "The sum is: $sum."

(3)分別計算100以內所有偶數之和和奇數之和;
#!/bin/bash
#
declare -i oddSum=0, evenSum=0
for i in `seq 1 2 100`; do
    oddSum=$[$oddSum+$i]
done

for j in `seq 2 2 100`; do
    evenSum=$[$evenSum+$j]
done
echo "The even Sum is: $evenSum, the odd sum is: $oddSum"



(2)變量的類型

    本地變量:只對當前shell進程有效,對其子shell及其他shell都無效;

        定義變量:[set]Var_Name="Value"

        引用變量:${Var_Name}

        撤銷變量:unset Var_Name

    局部變量:僅對局部代碼生效;

        local Var_Name="Value"

    環境變量:對當前shell進程及其子進程有效;

        export Var_Name="Value"

    位置參數變量:

        $0:腳本自身

(4)#!/bin/bash
#
echo "The sum is: $[$1+$2]"
echo $0
# ./opt.sh 10 11 
The sum is: 21
./opt.sh


        $1:腳本的第一個參數

        $2:腳本的第二個參數

         ....

(5)     

#!/bin/bash
#
echo "The sum is: $[$1+$2]"

#chmod +x opt.sh
#./opt.sh 10 11
The sum is: 21


    特殊變量

             $#:位置參數的個數;

# ./opt.sh 10 11 9 8
The sum is: 21
4


         $*,$@:引用所有的位置參數

(6)

#!/bin/bash
#
echo "The sum is: $[$1+$2]"
echo $*
echo $@
# ./opt.sh 10 11 9 8
The sum is: 21
10 11 9 8
10 11 9 8

         $?:上一條命令的執行狀態

            狀態用數字表示:

            0:表示成功

            1-255:失敗

   

        給變量以默認值

            varName=${varName:-value}

            如果varName不空,則其值不變;否則,VarName會使用value做爲其值;

wKioL1bm2cmQT1PbAAAdgYpWKtU227.png

        read:用戶交互腳本;

        -p:提示符

        -t [n]:超時時間

(7)

#!/bin/bash
#
read -t 5 -p "Enter a number: " num

num=${num:-0}
echo $num
# ./num1.sh 
Enter a number: 0     #上面-t指定的超時時間爲5秒鐘,如果執行腳本之後等5秒鐘(或直接回車),就會把設定的默認值顯示出來;

(8)通過鍵盤給定一個文件的路徑,來判斷文件內容的類型:
vim judge.sh
#!/bin/bash
#
read -p "Enter a file path: " fileName
file $fileName

bash judge.sh
Enter a file path: /etc/issue
/etc/issue: ASCII text


二、Bash編程之條件判斷:

    條件判斷的常用測試類型:

       整數測試

       字符測試

       文件測試

    命令狀態返回值:

        $?

        0:真

        1-255:假

    邏輯運算:

    與運算:

      真 && 真 = 真

      真 && 假 = 假

      假 && 真 = 假

      假 && 假 = 假

    或運算:

       真 || 真 = 真

       真 || 假 = 真

       假 || 真 = 真

       假 || 假 = 假

    非運算:

       !真 = 假

       !假 = 真


Bash中條件判斷中if的使用;

    單分支:

       if 條件;then

           分支1

       fi

    雙分支:

       if 條件;then

           分支1

       else

           分支2

       fi

    多分支:

       if 條件1;then

           分支1;

       elif 條件2;then

           分支2;then

       elif 條件3;then

           分支3;

       .....

       else

           分支n;

       fi

示例:

(9)讓用戶指定一個文件,判定;如果文件有空白行,就顯示空白行數,否則,就說明文件無空白行;

#!/bin/bash
#
read–p “Enter a file path: ” filename
if grep “^$”$fileName &> /dev/null; then
    linesCount=`grep “^$” $fileName | wc -l`
    echo “$fileName has $linesCount space lines.”
else
    echo “$fileName hava no space line.”
fi

(10)

顯示如下菜單:

cpu)show cpu info;

mem)show memory info;

quit)quit

Enter your options: CPU Cpu Cpu

如果用戶選擇cpu,則顯示文件/proc/cpuinfo的信息;

無果用戶選擇mem,則顯示文件/proc/meminfo的信息;

如果用戶選擇quit,則退出,並且退出嗎爲5;

如果用戶鍵入其他字符,則顯示位置選項,請重新執行腳本;退出碼爲6;

vim showinfo.sh
#!/bin/bash
#
returnValue=0

cat << EOF
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
EOF

read -p "Enter your option: " userOption
userOption=`echo $userOption | tr 'A-Z' 'a-z'`

if [[ "$userOption" == "cpu" ]]; then
    cat /proc/cpuinfo
elif [[ "$userOption" == "mem" ]]; then
    cat /proc/meminfo
elif [[ "$userOption" == "quit" ]]; then
    echo "quit"
    returnValue=6
else
    echo "unkown option"
    returnValue=7
fi

exit $returnValue



# bash showinfo.sh 
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
Enter your option: Cpu
processor    : 0
vendor_id    : GenuineIntel
cpu family    : 6
model        : 61
model name    : Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz
stepping    : 4
microcode    : 0x12
cpu MHz        : 2194.940
cache size    : 3072 KB
physical id    : 0
......
## bash showinfo.sh 
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
Enter your option: mem
MemTotal:        1001364 kB
MemFree:          398512 kB
MemAvailable:     605652 kB
Buffers:            2164 kB
Cached:           204948 kB
SwapCached:            0 kB
Active:           162280 kB
Inactive:         102440 kB
Active(anon):      67388 kB
Inactive(anon):    15868 kB
Active(file):      94892 kB
Inactive(file):    86572 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       2098172 kB
SwapFree:        2098172 kB
Dirty:                 0 kB
.......

#bash showinfo.sh 
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
Enter your option: quit
quit
# echo $?
6

# bash showinfo.sh 
cpu) print cpu infomation
mem) print memory infomation
quit) Quit
Enter your option: hello
unkown option
# echo $?
7


測試表達式:

    test 測試表達式

    [ 測試表達式 ]

    [[ 測試表達式 ]]

1、整數測試:

        -eq:是否等於

        -ne:是否不等

        -gt:大於

        -lt:小於

        -ge:大於等於

        -le:小於等於

(11)判定兩個數誰大誰小,整數是通過命令行參數傳遞;

vim j.sh
#!/bin/bash
#
if [ $1 –gt $2 ]; then
    echo “The max num is $1.”
else
    echo “The max num is $2.”
fi
#bash j.sh 56 34
Themax num is 56
#Bash j.sh 56 134
The max nu is 134

(12)腳本自定義退出:exit [n]

vim hello.sh
#!/bin/bash
#
echo“hello world”
exit6
echo“hello”
#bash hello.sh
hello world
#echo $?
6

(13)判定兩個數誰大誰小,參數輸入錯誤,則自定義退出,整數是通過命令行參數傳遞;

vimj.sh
#!/bin/bash
#
if [ $# -lt 2 ]; then
    echo “Stupid...”
    echo “Usage: `basename $0` argu1 argu2”
    exit 4
fi 
 
if[ $1 –gt $2 ]; then
    echo “The max num is $1.”
else
    echo “The max num is $2”
fi
#bash j.sh 3
Stupid...
Usage:j.sh argu1 argu2
#bash j.sh 3 6
The max num is 6

(14)讓用戶通過鍵盤輸入一個用戶名,如果用戶存在,就顯示其用戶名和UID;否則,就顯示用戶不存在;

#!/bin/bash
#
read –t 10 –p “Enter a username: ”username
if id $userName &> /dev/null; then
    userID=`id –u $userName`
    echo “$userName: $userID”
else
    echo “$userName not exist.”
fi

(15)讓用戶通過鍵盤輸入一個用戶名,如果用戶不存在就退出;如果其UID等於其GID,就說他是“good guy” 否則,就說他是個“bad guy”;

#!/bin/bash
#
read -t 10 -p "Enter a username: " userName
if ! id $userName &> /dev/null; then
    echo "$userName not exist."
    exit 6
fi

if [ `id -u $userName` -eq `id -g $userName` ]; then
    echo "Good guy"
else
    echo "Bad guy"
fi

(16)添加10個用戶stu1-stu10;但要先判斷用戶是否存在;

如果存在,就用紅色顯示其已經存在;

否則,就添加此用戶,並綠色顯示;

最後顯示一共添加了幾個用戶;

vim user.sh
#!/bin/bash
#
declare -i userCount=0
for i in {1..10}; do
    if id stu$i &> /dev/null; then
        echo -e "\033[31mstu$i\033[0m exists."
    else
        useradd stu$i && echo -e "add \033[32mstu$i\033[0m finished."
        let userCount++
    fi
done
echo "Add $userCount users."

# bash user.sh 
add stu1 finished.
add stu2 finished.
add stu3 finished.
add stu4 finished.
add stu5 finished.
add stu6 finished.
add stu7 finished.
add stu8 finished.
add stu9 finished.
add stu10 finished.
Add 10 users.

2、字符測試

    雙目:

    >:大於

    <:小於

    ==:等於,等值比較

    =~:左側字符串是否能夠被右側的PATTREN所匹配(包含)

 ==:

# stringA="root"
# stringB="root"
# [ "$stringA" == "$stringB" ]
# echo $?
0
測試是否相等?結果是肯定的。

 =~: 測試userName變量中的值是否包含了“ot”這樣的字符串;

# userName=root
# [[ "$userName" =~ ot ]]
# echo $?
0

給一個用戶名,判斷這個用戶的shell是不是以“sh”結尾的;

#userName=root
#$[[ `grep "^$userName\>" /etc/passwd | cut -d: -f7` =~ sh$ ]]
#echo $?
0


    單目:

    -n $stringVar:字符串是否不空,不空爲真,空則爲假;

測試stringA是否非空,非空爲真,否則爲假;

#stringA=root
# [ -n "$stringA" ]
# echo $?
0


    -z $stringVar: 字符串是否爲空,空則爲真,不空則假;

測試stringA是否爲空,空則真,否則爲假;

# [ -z "$stringA" ]
# echo $?
1

3、文件測試

測試表達式:

    test 測試表達式

    [ 測試表達式 ]

    [[ 測試表達式 ]]


    單目測試:

    -e file:測試文件是否存在;存在爲真,否則爲假;

    -a file: 和-e一樣

   文件類型測試

     -f /path/to/file:測試是否爲普通文件;

    -d /path/to/somefile:測試是否爲目錄文件;

    -b /path/to/somefile:測試文件是否存在並且是否是一個塊設備文件;

    -c /path/to/somefile:測試是否爲字符設備文件;

    -h或者-L /path/to/somefile:測試文件是否存在並且爲符號鏈接文件;

    -p /path/to/somefile:測試文件是否存在並且爲管道文件;

    -S /path/to/somefile:測試文件是否存在並且爲套接字文件;

    -s /path/to/somefile:測試文件是否不空,不空爲真,否則爲假;

    文件的權限測試:

    -r /path/to/somefile:測試當前用戶對此文件是否有讀權限;

    -w /path/to/somefile:測試當前用戶對此文件是否有寫權限;

    -x /path/to/somefile:測試當前用戶對此文件是否有執行權限;

    

    雙目測試:

    file1 -nt file2:測試file1是否比file2更新一些;

    file1 -ef file2: 是否指向同一文件系統的相同inode的硬鏈接;

    file1 -ot file2: file1文件是否舊於file2


示例:

(17)

#vim download.sh

#!/bin/bash
#
url=`http://172.16.0.1/centos6.5.repo`
which wget &> /dev/null || exit 5

downloader=`which wget`

[ -x $downloader ] || exit 6

$downloader $url

#bash download.sh

wKioL1bqRiPxiOLeAAIplEqXLzQ309.png

(18)

分別複製/var/log下的文件至/tmp/logs/目錄中;

複製目錄時,才使用cp -r

複製文件時,才使用cp

複製鏈接文件,使用cp -d

如果是其他文件,使用cp -a

vim cplog.sh

#!/bin/bash
#
targetDir='/tmp/logs'

[ -e $targetDir ] || mkdir $targetDir

for fileName in /var/log/*; do
    if [ -d $fileName ]; then
        copyCommand='cp -r'
    elif [ -f $fileName ]; then
        copyCommand='cp'
    elif [ -h $fileName ]; then
        copyCommand='cp -d'
    else
        copyCommand='cp -a'
    fi
    
    $copyCommand $fileName $targetDir
done








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章