Linux_《Linux命令行與shell腳本編程大全》第十二章學習總結

時間:2017年08月31日星期四
說明:本文部份內容均摘取自書籍《Linux命令行與shell腳本編程大全》,版權歸原做者全部。《Linux命令行與shell腳本編程大全》(第三版)第十二章學習總結程序員

第十二章:使用結構化命令

本章內容shell

使用if-then語句
嵌套if語句
test命令
複合條件測試
使用雙方括號和雙括號
case命令

12.1 使用if-then語句

語句格式:express

if command
then
command
fi

編程

if command; then
command
fi

語句說明:bash shell的if語句會運行if後面的那個命令,若是該命令的退出狀態碼是0(該命令執行成功),則位於then部分的命令就回被執行。若是不是0,則不執行then部分的命令,繼續執行腳本中的下一個命令。fi語句表示if-then語句到此結束。bash

編寫test1.sh腳本less

#!/bin/bash
# testing the if statement
if pwd
then
    echo It worked
fi

編寫test2.sh腳本ide

#!/bin/bash
# testing a bad command
if IamNotaCommand
then 
    echo "It worked"
fi
echo "We are outside the if statement"

編寫test3.sh腳本學習

#!/bin/bash
if grep $testuser /etc/passwd
then 
    echo "This is my first command"
    echo "This is my second command" 
    echo "I can even put in other commands besides echo:"
    ls -a /home/$testuser/.b*
fi

12.2 if-then-else語句

語句格式測試

if command
then 
command
else
command
fi

語句說明:當if語句中的命令返回退出狀態碼爲0時,then部分中的命令會被執行;當狀態碼不爲0時,else部分中的命令會被執行。this

編寫test4.sh腳本

#!/bin/bash
# testing multiple commands in the then section

testuser=nosuchuser

if grep $testuser /etc/passwd
then 
    echo "This is my first command"
    echo "This is my second command" 
    echo "I can even put in other commands besides echo:"
    ls -a /home/$testuser/.b*
else
    echo "The user $testuser does not exist on this system."
fi

12.3 嵌套if

要檢查/etc/passwd文件中是否存在某個用戶以及該用戶的目錄是否尚在,可使用嵌套的if-then語句。嵌套的if-then語句位於主if-then-else語句的else代碼塊中。

語句格式

if command1
then
commands
elif command2
then
more commands
else
moreandmore commands
fi

語句說明:先執行command1,返回狀態碼爲0時,執行commands,從elif到fi之間的命令則跳過。當command1返回狀態碼不爲0時,則執行command2,command2的返回狀態碼爲0,則執行more commands;不爲0,則執行moreandmore commands。

編寫test5.sh腳本

#!/bin/bash
# testing nested ifs - use elif

testuser=nosuchuser

if grep $testuser /etc/passwd
then
    echo "The user $testuser exists on this system."
elif ls -d /home/$testuser
then
    echo "The user $testuser dose not exist on this system."
    echo "However,$testuser has a directory"
else
    echo "The user $testuser dose not exist on this system."
    echo "And,$testuser dose not have a directory"
fi

竅門:在elif語句中,緊跟其後的else語句屬於elif代碼塊。它們並不屬於以前的if-then代碼塊。

能夠將多個elif語句串起來

if command1
then
command set 1
elif command2
then
command set 2
elif command3
then
command set 3
elif command4
then
command set 5
fi

12.4 test命令

命令格式:test condition

命令說明:若是test命令中列出的條件成立,test命令就回返回0,不然返回非零的狀態碼,這樣就能夠結合if-then語句使用。

語句格式

if test condition
then
commands
fi

語句說明:若是test命令的condition部分爲空時,它會返回非零的退出狀態碼。

語句格式

if [ condition ]
then
commands
fi

語句說明:bash shell提供的另外一種測試方法,第一個方括號以後和第二個方括號以前必須加一個空格。

test命令能夠判斷三類條件

數值比較
字符串比較
文件比較

12.4.1 數值比較

test命令的數值比較功能

n1 -eq n2:檢查n1是否等於n2
n1 -gen2:檢查n1是否大於或等於n2
n1 -gt n2:檢查n1是否大於n2
n1 -le n2:檢查n1是否小於或等於n2
n1 -lt n2:檢查n1是否小於n2
n1 -ne n2:檢查n1是否不等於n2

編寫numberic_test.sh腳本

#!/bin/bash
value1=10
value2=11
#
if [ $value1 -gt 5 ]
then
    echo "The test value $value1 is greater then 5"
fi
#
if [ $value1 -eq $value2 ]
then
    echo "The values are equal"
else
    echo "The values are different"
fi

bash shell只能處理整數。若是隻是經過echo來顯示浮點數,則沒問題;若是用於數值比較,則會出錯。

編寫floating_point_test.sh腳本

#!/bin/bash
#
value1=5.555
#
echo "The test value is $value1"
#
if [ $value1 -gt 5 ]
then
    echo "The test value $value1 is greater then 5"
fi

12.4.2 字符串比較

字符串比較測試

str1 = str2:檢查str1是否和str2相同
str1 != str2:檢查str1是否和str2不一樣
str1 < str2:檢查str1是否比str2小(使用時大於符號注意轉義)
str1 > str2:檢查str1是否比str2大(使用時小於符號注意轉義)
-n str2:檢查str1的長度是否非0
-z str2:檢查str1的長度是否爲0

1.字符串相等性

編寫test7.sh腳本

#!/bin/bash
# testing string equality
testuser=rich
#
if [ $USER = $testuser ]
then
    echo "Welcome $testuser"
else
    echo "This is not $testuser"
fi

編寫test8.sh腳本

#!/bin/bash
# testing string equality
testuser=rich
#
if [ $USER != $testuser ]
then
    echo "This is not $testuser" 
else
    echo "Welcome $testuser"  
fi

2.字符串順序

編寫test9.sh腳本

#!/bin/bash
# mis-using string comparisons
#
val1=baseball
val2=hockey
#
if [ $val1 \> $val2 ]
then
    echo "$val1 is greater than $val2" 
else
    echo "$val1 is less than $val2"
fi

注意:在進行字符串比較時,使用的是標準的ASCII順序,根據每一個字符的ASCII數值來決定排序結果,大寫字母被認爲是小於小寫字母的。但sort命令剛好相反。

說明:test命令和測試表達式使用標準的數學比較符號來表示字符串比較,而用文本代碼(如:-eq,-ge等)來表示數值比較。這個細微的特性被不少程序員理解反了。若是你對數值使用了數據運算符,shell會將它們當成字符串值,可能沒法獲得正確的結果。

3.字符串大小

編寫test10.sh腳本

#!/bin/bash
# testing string length
val1=testing
val2=''
#
if [ -n $val1 ]
then
    echo "The string '$val1' is not empty" 
else
    echo "The string '$val1' is empty"
fi
#
if [ -z $val2 ] 
then
    echo "The string '$val2' is empty"
else
    echo "The string '$val2' is not empty"
fi
#
if [ -z $val3 ] 
then
    echo "The string '$val3' is empty"
else
    echo "The string '$val3' is not empty"
fi

敲門:空的和未初始化的變量會對shell腳本測試形成災難性的影響。若是不是很肯定一個變量的內容,最好在將其用於數值或字符串比較以前先經過-n或-z來測試一下變量是否含有值。

12.4.3 文件比較

test命令的文件比較功能

-d file:檢查file是否存在並是一個目錄
-e file:檢查file是否存在
-f file:檢查file是否存在並是一個文件
-r file:檢查file是否存在並可讀
-s file:檢查file是否存在並不是空
-w file:檢查file是否存在並可寫
-x file:檢查file是否存在並可執行
-O file:檢查file是否存在並屬當前用戶全部
-G file:檢查file是否存在而且默認組與當前用戶相同
file1 -nt file2:檢查file1是否比file2新
file1 -ot file2:檢查file1是否比file2舊

1.檢查目錄

-d測試會檢查指定的目錄是否存在於系統中。若是你打算將文件寫入目錄或是準備切換到某個目錄中,先進行測試老是件好事情

編寫test11.sh腳本

#!/bin/bash
# Look before you leap
#
jump_directory=/home/zc
#
if [ -d $jump_directory ]
then
    echo "The $jump_directory directory exists"
    cd $jump_directory
    ls
else
    echo "The $jump_directory directory dose not exist"
fi

2.檢查對象是否存在

-e比較容許你的腳本代碼在使用文件或目錄前先檢查它們是否存在

編寫test12.sh腳本

#!/bin/bash
# Check if either a directory or file exists
#
location=$HOME
file_name="sentinel"
#
if [ -e $location ]
then #Directory does exist
    echo "OK on the $location directory."
    echo "Now checking on the file, $file_name."
    #
    if [ -e $location/$file_name ]
    then #File does exist
        echo "OK on the filename"
        echo "Updating Current Date..."
        date >> $location/$file_name
    #
    else #File does not exist
        echo "File does not exist"
        echo "Nothing to update"
    fi
#
else #Directory does not exist
    echo "The $location directory does not exist."
    echo "Nothing to update"
fi

3.檢查文件

-e比較可用於文件和目錄。要肯定指定對象爲文件,必須用-f比較

編寫test12.sh

#!/bin/bash
# check if either a directory or file exists
#
item_name=$HOME
echo
echo "The item being checked: $item_name"
echo
#
if [ -e $item_name ]
then #Item does exist
    echo "The item, $item_name, does exist."
    echo "But is it a file?"
    echo
    #
    if [ -f $item_name ]
    then #Item is a file
        echo "Yes, $item_name is a file."
    #
    else #Item is not a file
        echo "No, $item_name is not a file."
    fi
#
else #Item does not exist
    echo "The item, $item_name, does not exist."
    echo "Nothing to update"
fi

4.檢查是否可讀

在嘗試從文件中讀取數據以前,最好先測試一下文件是否可讀,可使用-r比較測試

編寫test14.sh腳本

#!/bin/bash
# testing if you can read a file
pwfile=/etc/shadow
#
# first, test if the file exists, and is a file
if [ -f $pwfile ]
then
    # now test if you can read it
    if [ -r $pwfile ]
    then
        tail $pwfile
    else
        echo "Sorry, I am unable to read the $pwfile file"
    fi
else
    echo "Sorry, the file $pwfile does not exist"
fi

5.檢查空文件

使用-s比較來檢查文件是否爲空,當-s比較成功時,說明文件中有數據。

編寫test15.sh腳本

#!/bin/bash
# Testing if a file is empty
#
file_name=$HOME/sentinel
#
if [ -f $file_name ]
then
    if [-s $file_name ]
    then
        echo "The $file_name file exists and has data in it."
        echo "Will not remove this file."
    else
        echo "The $file_name file exists,but is empty."
        echo "Deleting empty file..."
        rm $file_name
    fi
else
    echo "File,$file_name,does not exist."
fi

6.檢查是否可寫

使用-w比較進行判斷你對文件是否有可寫權限

編寫test16.sh腳本

#!/bin/bash
# check if a file is writable.
#
item_name=$HOME/sentinel
echo
echo "The item being checked: $item_name"
echo
#
if [ -e $item_name ]
then #Item does exist
    echo "The item, $item_name, does exist."
    echo "But is it a file?"
    echo
    #
    if [ -f $item_name ]
    then #Item is a file
        echo "Yes, $item_name is a file."
        echo "But is it writable?"
        echo
        #
        if [ -w $item_name ]
        then #Item is writable
            echo "Writing current time to $item_name"
            date +$H$M >> $item_name
        #
        else #Item is not writable
            echo "Unable to write to $item_name"
        fi
    #
    else #Item is not a file
        echo "No, $item_name is not a file."
    fi
#
else #Item does not exist
    echo "The item, $item_name, does not exist."
    echo "Nothing to update"
fi

7.檢查文件是否能夠執行

使用-x比較判斷特定文件是否有執行權限

編寫test17.sh腳本

#!/bin/bash
# testing file execution
#
if [ -x test16.sh ]
then 
    echo "You can run the script:"
    ./test16.sh
else
    echo "Sorry, you are unable to execute the script"
fi

8.檢查所屬關係

使用-O比較測試當前用戶是不是文件的屬主

編寫test18.sh腳本

#!/bin/bash
# eheck file ownership
#
if [ -O /etc/passwd ]
then 
    echo "You are the owner of the /etc/passwd file"
else
    echo "Sorry, you are not the owner of the /etc/passwd file"
fi

9.檢查默認屬組關係

使用-G比較檢查文件的默認組,若是它匹配了用戶的默認組,則測試成功。注:-G比較只會檢查默認組而非用戶所屬的全部組。

編寫test19.sh腳本

#!/bin/bash
# check file group test
#
if [ -G $HOME/testing ]
then
    echo "You are in the same group as the file"
else
    echo  "The file is not owned by you group"
fi

10.檢查文件日期

使用-nt比較判斷一個文件是否比另外一個文件新。若是文件較新,則文件的建立日期更近。
使用-ot比較判斷一個文件是否比另外一個文件舊。若是文件較舊,則文件的建立日期更早。

編寫test20.sh腳本

#!/bin/bash
# testing file dates 
#
if [ test19.sh -nt test18.sh ]
then
    echo "The test19 file is newer than test18"
else
    echo "The test18 file is newer than test19"
fi
if [ test17.sh -ot test19.sh ]
then
    echo "The test17 file is older than the test19 file"
fi

編寫test21.sh腳本

#!/bin/bash
# testing file dates 
#
if [ badfile1 -nt badfile2 ]
then
    echo "The badfile1 file is newer than badfile2"
else
    echo "The badfile2 file is newer than badfile1"
fi

注意:這些命令都沒有檢查文件是否存在,在使用這些命令以前,必須先確認文件是存在的

12.5 複合條件測試

if-then語句容許使用布爾邏輯來組合測試,格式以下

[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]

竅門:布爾邏輯是一種可以將可能的返回值簡化爲TRUE或FALSE的方法

編寫test22.sh腳本

#!/bin/bash
# testing compound comparisons
#
if [ -d $HOME ] && [ -w $HOME/testing ]
then
    echo "The file exists and you can write to it"
else
    echo "I connot write to the file"
fi

12.6 if-then的高級特性

12.6.1 使用雙括號

命令格式:(( expression ))
命令說明:使用雙括號能夠在比較過程當中使用高級數據表達式

雙括號命令符號

val++:後自增
val--:後自減
++val:先自增
--val:先自減
!:邏輯求反
~:位求反
**:冪運算
<<:左位移
>>:右位移
&:位布爾與
|:位布爾或
&&:邏輯與
||:邏輯或

編寫test23.sh腳本

#!/bin/bash
# using double parenthesis
#
var1=10
#
if (( $val1 ** 2 > 90 ))
then
    (( val2 = $val1 ** 2 ))  
    echo "The square of $val1 is $val2"
fi

12.6.2 使用雙方括號

命令格式:[[ expression ]]
命令說明:在單方括號的基礎上,增長了模式匹配
命令注意:並非全部的shell都支持雙方括號

編寫test24.sh腳本

#!/bin/bash
# using pattern matching
#
if [[ $USER == z* ]]
then
    echo "Hello $USER"
else
    echo "Sorry,I do not know you"
fi

12.7 case命令

編寫test25.sh腳本

#!/bin/bash
# looking for a possible value
#
if [ $USER = "zc" ]
then
    echo "Welcome $USER"
    echo "Please enjoy your visit"
elif [ $USER = "barbara" ]
then
    echo "Welcome $USER"
    echo "Please enjoy your visit"
elif [ $USER = "testing" ]
then
    echo "Special testing account"
elif [ $USER = "jessica" ]
then
    echo "Do not forget to logout when you're done"
else
    echo "Sorry, you are not allowd here"
fi

命令格式:

case variable in
      pattern1 | pattern2) commands1;;
      pattern3) commands2;;
      *) commands3;;
      esac

命令說明:case命令會將指定的變量與不一樣模式進行比較

編寫test26.sh腳本

#!/bin/bash
# looking for a possible value
#
if [ $USER = "zc" ]
then
    echo "Welcome $USER"
    echo "Please enjoy your visit"
elif [ $USER = "barbara" ]
then
    echo "Welcome $USER"
    echo "Please enjoy your visit"
elif [ $USER = "testing" ]
then
    echo "Special testing account"
elif [ $USER = "jessica" ]
then
    echo "Do not forget to logout when you're done"
else
    echo "Sorry, you are not allowd here"
fi

12.8 小結

結構化命令能夠改變shell腳本的正常執行流。最基本的結構化命令是if-then語句。該語句能夠根據一個執行一個命令的結果來執行其餘命令。本章介紹了if-then、if-then-else、elif、case語句。

相關文章
相關標籤/搜索