03_shell_控制流結構

什麼是流控制

#!/bin/bash
#創建一個目錄
    make /home/wbm/shell/txt
#複製所有txt文件到指定目錄 
    cp *.txt /home/wbm/shell/txt
    rm -f *txt

--------------------------------------------
上述腳本會出現問題嗎?
如果目錄創建失敗或成功如何處理
文件拷貝失敗如何處理

test 條件測試

有時判斷字符串是否相等或檢查文件狀態或是數字測試等。
Test命令用於測試字符串,文件狀態和數字
如果test命令中列出的條件成立,test命令就會退出並返回退出狀態碼0

==文件狀態測試

 格式    test condition    或 [ condition ]

//使用方括號時,要注意在條件兩邊加上空格!!!!!!!!!!!!

-d     目錄               
-s     文件長度大於0、非空
-f     正規文件          
-w     可寫
-L     符號鏈接          
-u     文件有suid位設置
-r     可讀              
-x     可執行
-z     字符串爲空


hzmct@U-64:/study/linuxtest/day03$ help test
test: test [expr]
    Evaluate conditional expression.

    Exits with a status of 0 (true) or 1 (false) depending on
    the evaluation of EXPR.  Expressions may be unary or binary.  Unary
    expressions are often used to examine the status of a file.  There
    are string operators and numeric comparison operators as well.

    The behavior of test depends on the number of arguments.  Read the
    bash manual page for the complete specification.

    File operators:

      -a FILE        True if file exists.
      -b FILE        True if file is block special.
      -c FILE        True if file is character special.
      -d FILE        True if file is a directory.
      -e FILE        True if file exists.
      -f FILE        True if file exists and is a regular file.
      -g FILE        True if file is set-group-id.
      -h FILE        True if file is a symbolic link.
      -L FILE        True if file is a symbolic link.
      -k FILE        True if file has its `sticky' bit set.
      -p FILE        True if file is a named pipe.
      -r FILE        True if file is readable by you.
      -s FILE        True if file exists and is not empty.
      -S FILE        True if file is a socket.
      -t FD          True if FD is opened on a terminal.
      -u FILE        True if the file is set-user-id.
      -w FILE        True if the file is writable by you.
      -x FILE        True if the file is executable by you.
      -O FILE        True if the file is effectively owned by you.
      -G FILE        True if the file is effectively owned by your group.
      -N FILE        True if the file has been modified since it was last read.

      FILE1 -nt FILE2  True if file1 is newer than file2 (according to
                       modification date).

      FILE1 -ot FILE2  True if file1 is older than file2.

      FILE1 -ef FILE2  True if file1 is a hard link to file2.

    All file operators except -h and -L are acting on the target of a symbolic
    link, not on the symlink itself, if FILE is a symbolic link.

    String operators:

      -z STRING      True if string is empty.

      -n STRING
         STRING      True if string is not empty.

      STRING1 = STRING2
                     True if the strings are equal.
      STRING1 != STRING2
                     True if the strings are not equal.
      STRING1 < STRING2
                     True if STRING1 sorts before STRING2 lexicographically.
      STRING1 > STRING2
                     True if STRING1 sorts after STRING2 lexicographically.

    Other operators:

      -o OPTION      True if the shell option OPTION is enabled.
      -v VAR     True if the shell variable VAR is set
      -R VAR     True if the shell variable VAR is set and is a name reference.
      ! EXPR         True if expr is false.
      EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
      EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.

      arg1 OP arg2   Arithmetic tests.  OP is one of -eq, -ne,
                     -lt, -le, -gt, or -ge.

    Arithmetic binary operators return true if ARG1 is equal, not-equal,
    less-than, less-than-or-equal, greater-than, or greater-than-or-equal
    than ARG2.

    See the bash manual page bash(1) for the handling of parameters (i.e.
    missing parameters).

    Exit Status:
    Returns success if EXPR evaluates to true; fails if EXPR evaluates to
    false or an invalid argument is given.
//eg1 使用test指令
$ test -d dir
//顯示前一個命令的運行狀態
$ echo $?
1

//eg2 使用[空格 表達式 空格]
$ [ -w 1 -a -x 2 ]
$ echo $?
1

//eg3  使用腳本
hzmct@U-64:/study/linuxtest/day03$ cat 6testdir.sh 
#!/bin/bash
echo "test 命令使用 方法1"
test -d "mulu"
#顯示上一個命令執行是否成功 0表示成功
echo $?
#使用[]運算將表達式包含起來
echo "test命令使用 方法 2 []"
[ -d "mulu" ]
echo $?

==字符串測試

格式如下:
test "string"
test string_operator "string"
test "string" string_operator "string"

[]方法
[ string_operator string ]
[string string_operator string ]
使用方括號時,要注意在條件兩邊加上空格

測試兩個字符是否相等。退出狀態變量 $?0表示成功,1表示失敗。
操作數string_operator   
=     兩個字符串相等
!=    兩個字符串不等
-z    空串
-n    非空串


eg
hzmct@U-64:~$ echo $chen

hzmct@U-64:~$ [ -z $chen ]
hzmct@U-64:~$ echo $?
0

eg
hzmct@U-64:~$ aa="123"
hzmct@U-64:~$ bb="456"
hzmct@U-64:~$ [ "$aa"="bb" ]//錯誤的寫法
hzmct@U-64:~$ echo $?
0
//= 兩邊要有空格!!!
hzmct@U-64:~$ [ "$aa" = "$bb" ]//正確的寫法
hzmct@U-64:~$ echo $?
1
hzmct@U-64:~$ [ "$aa" = "$aa" ]
hzmct@U-64:~$ echo $?
0

==測試數值

格式    測試兩個數值大小
    "number" numberic_operator "number"
    或者
    [ "number" numberic_operator "number" ]
    numberic_operator可爲:
    -eq         數值相等。
    -ne         數值不相等。
    -gt         第一個數大於第二個數。
    -lt         第一個數小於第二個數。
    -le         第一個數小於等於第二個數。
    -ge         第一個數大於等於第二個數。

eg:
hzmct@U-64:~$ a1=10
hzmct@U-64:~$ a2=12
hzmct@U-64:~$ [ "$a1" -eq "13" ]
hzmct@U-64:~$ echo $?
1
hzmct@U-64:~$ [ "$a1" -eq "10" ]
hzmct@U-64:~$ echo $?
0

expr數字運算

expr argument operator argument
加法運算:expr 10 + 10
減法運算:expr 20 - 10
加法運算:expr 10 / 5
乘法運算:expr 10 \* 5

eg
hzmct@U-64:~$ expr 10 + 10
20
hzmct@U-64:~$ expr 10+10  //錯誤的寫法 
10+10

hzmct@U-64:~$ expr 10 * 10
expr: syntax error

//使用乘號時也要用反斜線屏蔽其特殊意義
hzmct@U-64:~$ expr 10 \* 10
100
hzmct@U-64:~$ 


if-then

使用if-then 語句
if command
then 
    command
fi
注意:
    bash shell的if語句會運行if後面的那個命令。如果該命令的退出狀態碼是0(該命令成功運行),位於then部分的命令就會被執行。如果該命令的退出狀態碼是其他值, then部分的命令就不會被執行, bash shell會繼續執行腳本中的下一個命令。
     fi語句用來表示if-then語句到此結束。

常用的方式
if command; then 
    command
fi

//例子
hzmct@U-64:/study/linuxtest/day03$ cat 7if.sh 
#!/bin/bash
echo "test use 1"
#測試文件是否可寫
test -w tmp.txt
if [ $? -eq "0" ];then
    echo -e "success\n"
else
    echo -e  "not success\n"
fi
echo $?
echo "test use 2 [] begin"
 [ -w tmp.txt ]
echo $?

if then else

語法1
if command
then
    command
else
    command
fi

eg
hzmct@U-64:/study/linuxtest/day03$ cat 8ifelse.sh 
#!/bin/bash
if [ "13" -lt "12" ]
then
    echo "yes 13 is less than 12"
else
    echo "NO"
fi

if嵌套

if command1
then
    commands
elif commmand2
then
    commands
fi

eg:檢查文件是否爲空,若是空文件刪除
#!/bin/bash
echo -n "Enter your filename:"
read myfile
#-e 檢查文件是否存在
if [ -e $myfile ]; then
        if [ -s $myfile ]; then
        echo "$myfile exist and size greater than zero"
        echo "will not remove this file"
    else
        echo "$myfile exist but size is zero"
        echo "delete empty file ......"
        rm $myfile
    fi
else
    echo "file no exist"
fi


hzmct@U-64:/study/linuxtest/day03$ ./9ifif.sh 
Enter your filename:1
file no exist
hzmct@U-64:/study/linuxtest/day03$ touch 1
hzmct@U-64:/study/linuxtest/day03$ ./9ifif.sh 
Enter your filename:1
1 exist but size is zero
delete empty file ......

if-then的高級特性

bash shell提供了兩項可在if-then語句中使用的高級特性:
 用於數學表達式的雙括號
 用於高級字符串處理功能的雙方括號

==雙括號
表達式
(( expression))

expression可以是任意的數學賦值或比較表達式。除了test命令使用的標準數學運算符,
表12-4列出了雙括號命令中會用到的其他運算符
val++   後增
val--   後減
++val   先增
--val   先減
!       邏輯求反
~      位求反
**      冪運算
<<      左位移
>>      右位移
&       位布爾和
|       位布爾或
&&      邏輯和
||      邏輯或

hzmct@U-64:~$ echo $((10 ** 2))
100

hzmct@U-64:/study/linuxtest/day03$ cat 10ifshuangkuohao.sh 
#!/bin/bash
#using double parenthesis
var1=10
#不需要將雙括號中表達式裏的大於號轉義。這是雙括號命令提供的另一個高級特性
if (( $var1 ** 2 > 90)); then
    (( var2 = $var1 ** 2))
    echo "The square of $var1 is $var2"
fi

==雙方括號
雙方括號命令提供了針對字符串比較的高級特性。雙方括號命令的格式如下:
[[ expression ]]
雙方括號裏的expression使用了test命令中採用的標準字符串比較。但它提供了test命
令未提供的另一個特性——模式匹配(pattern matching)
說明 :雙方括號在bash shell中工作良好。不過要小心,不是所有的shell都支持雙方括號。
eg:
hzmct@U-64:/study/linuxtest/day03$ cat 11ifshuangfangkuohao.sh 
#!/bin/bash
#using pattern matching
#
if [[ $USER == r* ]]
then
    echo "Hello $USER"
else
    echo "Sorry, I do not know you"
fi


hzmct@U-64:/study/linuxtest/day03$ USER="rich"
hzmct@U-64:/study/linuxtest/day03$ ./11ifshuangfangkuohao.sh 
Hello rich

    使用了雙等號(==)。雙等號將右邊的字符串(r*)視爲一個模式,
並應用模式匹配規則。雙方括號命令$USER環境變量進行匹配,看它是否以字母r開頭。如果是
的話,比較通過, shell會執行then部分的命令。

case

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


case命令會將指定的變量與不同模式進行比較。如果變量和模式是匹配的,那麼shell會執行
爲該模式指定的命令。可以通過豎線操作符在一行中分隔出多個模式模式。星號會捕獲所有與已
知模式不匹配的值。

hzmct@U-64:/study/linuxtest/day03$ cat 12case.sh 
#!/bin/bash
#looking for a possible value
#
if [ $USER = "rich" ];then
    echo "welcom $USER"
    echo "please enjoy your visit"
elif  [ $USER = "barbara" ];then   
    echo "welcom $USER"
    echo "please enjoy your visit"

elif  [ $USER = "testing" ];then   
    echo "welcom $USER"
    echo "special testing account"
elif  [ $USER = "jessica" ];then   
    echo "Do not forget to logout when you're done"
fi
#case 實現
#using the case command
#
case $USER in
rich | barbara)
    echo "welcom, $USER";;
testing)
    echo "special testing account";;
jessica)
    echo "do not forget to log off when you are done";;
*)
    echo "sorry, you are not allowed here";;
esac

case多選擇語句格式:
casein
模式1)
    命令1
    ;;
模式2)
    命令2
    ;;
esac

1)case取值後面必須爲單詞in;每一模式必須以右括號結束。
2)取值可以爲變量或常數。匹配發現取值符合某一模式後,其後的所有命令開始執行,直到;;
3)模式匹配*表示任意字符; ?表示任意單字符; [..]表示類或範圍中任意字符

eg:
hzmct@U-64:/study/linuxtest/day03$ cat 13case.sh 
#!/bin/bash
echo -n "enter a number from 1 to 3:"
read num
case $num in
1)
    echo "you select 1"
    ;;

2)
    echo "you select 2"
    ;;
3)
    echo "you select 3"
    ;;
y|Y)
    echo "you select y/Y"
    ;;
*)
    echo " `basename $0` :this is not between 1 and 3">&2
    echo " $0 :this is not between 1 and 3">&2
    exit;
    ;;
esac

循環命令 for

語法格式:
for循環一般格式
for 變量名 in 列表
do 
    命令1
    命令2
done

1 當變量值在列表裏,for循環即執行依次所有命令,使用變量名訪問列表中取值。
2 命令可爲任何有效的shell命令和語句。變量名爲任意單詞。
3 in列表用法是可選擇,如果不用它,for循環使用命令行的位置參數。
4 in列表可以包含替換、字符串和文件名

eg:
#!/bin/bash
#簡單遍歷
for i in 1 2 3 4 5 
do
    echo $i
done

for i in aaa bbb ccc
do
    echo $i
done
#讀取文件
for loop in `cat myfile`
do
    echo $loop
done
#複雜字符的處理
for test in I don\'t know if "this'll" work in "New york"
do
    echo "word:$test"
done


hzmct@U-64:/study/linuxtest/day03$ ./14for.sh 
1
2
3
4
5
aaa
bbb
ccc
11
22
33
word:I
word:don't
word:know
word:if
word:this'll
word:work
word:in
word:New york
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章