天天看點

13.Linux shell程式設計(條件語句和标準輸出重定向)

(建立于2018/1/31)

條件語句

shell中的條件語句必須以fi結尾,否則會報錯syntax error: unexpected end of file

if else then 這裡的test指令意思就是test後的條件如果成立,則它就是0(真),否則就是非零(假)

#!/bin/bash
  2 
  3 var=""
  4 if test var                                                                        
  5 then 
  6 echo "success"
  7 else
  8 echo "failed"
  9 fi
           

if then elif then fi(相當于if else if語句)

1 #!/bin/bash                                                                        
  2 
  3 if test $var
  4 then echo "success"
  5 elif test haha
  6 then echo "haha"
  7 else echo "failed"
  8 fi
           

條件語句進行數字大小比較

-gt表示數學中的大于号>

其他符号的對應關系為

-eq:等于

-lt : 小于

-ne :不等于

-le :小于等于

1 #!/bin/bash                                                                        
  2 
  3 a=10
  4 b=5
  5 
  6 if [ $a -gt $b ]      //注意,[]中間一定有空格,否則會報錯 command not found
  7 then
  8         echo "$a is greater than $b"
  9 else
 10         echo "$a is smaller than $b"
 11 fi

           
字元串的比較

str1 == str2

str1 != str2

str1 < str2

-n str1 長度是否非零

-z str2 長度是否為0

1 #!/bin/bash
  2 
  3 str1="ren"
  4 str2="ming"
  5 str3=""
  6 str4="ren"
  7 
  8 if [ $str1 == $str4 ]                                                              
  9 then
 10         echo " str1 == str2"
 11 else
 12         echo " str1 != str2"
 13 fi
           
檢查檔案或者目錄

-d : 檢查目錄是否存在

-f : 檢查檔案是否存在

-e : 檢查檔案或者目錄是否存在

-r : 檢查是否存在并且可讀

-w : 檢查是否存在并且可寫

-x : 檢查是否存在并且可執行

file1 -nt file2 file1比file2新(new than)

file1 -ot file2 file1比file2舊 (old than)

檢視一個目錄是否存在,如果存在則周遊這個目錄

1 #!/bin/bash                                                                        
  2 
  3 dir=/usr/ndk/temp
  4 
  5 if [ -d $dir ]
  6 then
  7         echo "$dir exist"
  8         cd $dir
  9         ls
 10 else
 11         echo "$dir not exist"
 12 fi

           
多個條件組合

如果目錄存在和檔案ren.sh可執行滿足,則列印,周遊dir并建立一個檔案b.sh并授權可執行然後再次周遊

1 #!/bin/bash                                                                        
  2 
  3 dir=/usr/ndk/temp
  4 
  5 dir2=/usr/ndk/temp/ren.sh
  6 
  7 if [ -d $dir ] && [ -x $dir2 ]
  8 then
  9         echo "find $dir and $dir2,$dir2 can be execute"
 10         ls $dir
 11         touch b.sh
 12         chmod u+x b.sh
 13         ls -la
 14 else
 15         echo "not exist"
 16 fi


  tabstop=8root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# ./a.sh 
find /usr/ndk/temp and /usr/ndk/temp/ren.sh,/usr/ndk/temp/ren.sh can be execute
a.sh  ren.sh
total 16
d--------- 2 root root 4096 Sep 13 07:57 .
drwxrwxrwx 7 root root 4096 Sep  7 07:47 ..
-rwxr--r-- 1 root root  215 Sep 13 07:57 a.sh
-rwxr--r-- 1 root root    0 Sep 13 07:57 b.sh
-rwxr--r-- 1 root root  115 Sep 13 07:34 ren.sh
           
shell中的case指令(類似switch)

格式如下:

case 變量 in

pattern1) 指令;;

pattern2) 指令;;

*) 預設指令;;

esac

1 #!/bin/bash                                                                        
  2 
  3 user=zhen
  4 
  5 case $user in
  6 
  7 zhen)
  8         echo "zhen is here";;
  9 ming)
 10         echo "ming is here";;
 11 *)
 12         echo "not found";;
 13 esac

           

shell中的for指令

1 #!/bin/bash
  2 
  3 list="Monday,Friday,Sonday"
  4 IFS=$,          //域分隔符                                                                   
  5 for item in $list
  6 do
  7         echo $item
  8 done
  9 

列印結果去掉了括号
  tabstop=8root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# ./c.sh 
Monday
Friday
Sonday
           
shell中的while指令
1 #!/bin/bash                                                                        
  2 
  3 a=10
  4 while [ $a -gt 0 ]
  5 
  6 do
  7         echo "num:$a"
  8         a=$[ $a - 1 ]
  9 done

tabstop=8root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# ./d.sh 
num:10
num:9
num:8
num:7
num:6
num:5
num:4
num:3
num:2
num:1
root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# 

           

循環語句和條件語句嵌套

1 #!/bin/bash                                                                        
  2 
  3 a=10
  4 while [ $a -gt 0 ]
  5 
  6 do
  7         echo "num:$a"
  8         a=$[ $a - 1 ]
  9         if [ $a -eq 5 ]
 10         then
 11                 echo "break"
 12                 break
 13         fi
 14 done

  tabstop=8root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# ./d.sh 
num:10
num:9
num:8
num:7
num:6
break
root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp#
           

重定向深入了解undefined

一般情況下,每一個Linux 指令運作時都會打開三個檔案:

标準輸入檔案(stdin): stdin的檔案描述符為0,linux程式預設從stdin讀取資料。

标準輸出檔案(stdout): stdout 的檔案描述為1,linux程式預設向stdout輸出資料。

标準錯誤檔案(stderr): stderr 的檔案描述符為2,linux程式會向stderr流中寫入錯誤資訊。

以後打開檔案後。新增檔案綁定描述符 可以依次增加。 一條shell指令執行,都會繼承父程序的檔案描述符。是以,所有運作的shell指令,都會有預設3個檔案描述符。

正常情況下,command > file 将stdout重定向file,command < file 将stdin 重定向到 file。

一個指令執行了:

先有一個輸入:輸入可以從鍵盤,也可以從檔案得到

指令執行完成:成功了,會把成功結果輸出到螢幕:standard output預設是螢幕

指令執行有錯誤:會把錯誤也輸出到螢幕上面:standard error預設也是指的螢幕

如果希望stderr 重定向 到file 可以這樣寫:

command 2> file
1
           

如果希望stderr追加到file 檔案末尾,可以這樣寫:

command 2>> file
           

1.輸出内容到檔案中,(如果檔案不存在則自動建立)

#!/bin/bash                                                                              

file=test111
echo "input into test111" > $file
echo "input into test111" >> $file  (追加到檔案末尾)

打開檔案test111會發現結果,輸入了兩行
input into test111
input into test111
           

2.輸出到螢幕上(控制台)

#!/bin/bash                                                                              

file=test111

//0 STDIN
//1 STDOUT  标準輸出
//2 STDERR

echo "input into test111" >&2    //注意,>與&2之間沒有空格
echo "input into test111" >&2    //>>無法輸出到螢幕
           

3.在指令行中控制标準輸出重定向到檔案中

command > file  将輸出重定向到 file。
command < file  将輸入重定向到 file。
command >> file     将輸出以追加的方式重定向到 file。
n > file    将檔案描述符為 n 的檔案重定向到 file。
n >> file   将檔案描述符為 n 的檔案以追加的方式重定向到 file。
n >& m  将輸出檔案 m 和 n 合并。
n <& m  将輸入檔案 m 和 n 合并。
<< tag  将開始标記 tag 和結束标記 tag 之間的内容作為輸入。
需要注意的是檔案描述符 0 通常是标準輸入(STDIN),1 是标準輸出(STDOUT),2 是标準錯誤輸出(STDERR)。

command1 < infile > outfile   //執行command1,從檔案infile讀取内容,然後将輸出寫入到outfile中
           
#!/bin/bash                                                                              

file=test111
echo "input into test111"
echo "input into test111"
    
//./14.sh &> test222  也可以輸出到檔案中,搞不懂
執行腳本

tabstop=8root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ./14.sh 1> test222   //(将檔案描述符為 n 的檔案重定向到 file。)會将标準輸出符為1的檔案14.sh中的标準輸出内容重定向到test222檔案中,注意任何test222内的已經存在的内容将被新内容替代。如果要将新的内容添加到檔案的末尾,則使用>>操作符。
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ls
10.sh  12.sh  14.sh  3.sh  5.sh  7.sh  9.sh  ren.txt  test222
11.sh  13.sh  2.sh   4.sh  6.sh  8.sh  copy  test111
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat test222
input into test111
input into test111
           

4.在腳本中設定标準輸出重定向寫入檔案中,exec 1>檔案名

#!/bin/bash                                                                              

exec 1>test333
echo "input into test333"
echo "input into test333"
      
      
輸出結果:

./14.sh
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ls
10.sh  12.sh  14.sh  3.sh  5.sh  7.sh  9.sh  ren.txt  test222
11.sh  13.sh  2.sh   4.sh  6.sh  8.sh  copy  test111  test333
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat test333 


  1 #!/bin/bash                                                                        
  2 
  //将标準輸出重定向到output.txt檔案中,這樣一來這個腳本中的所有輸出内容會
  //被列印到output.txt檔案
  3 exec 1>output.txt
  //将标準錯誤輸出重定向到error.txt檔案,是以這個檔案中發生的錯誤資訊會被列印
  //到這裡
  4 exec 2>error.txt
  5 
  6 echo "this is output"
  7 ls -la ffmpeg
           

5.自定義輸出

#!/bin/bash   

//#0 STDIN    标準輸入
//#1 STDOUT   标準輸出
//#STDERR     标準錯誤

exec 1>file1      //将腳本執行過程中的标準輸出寫入到檔案file1
exec 2>file2      //将腳本執行中的标準錯誤輸出到檔案file2

exec 3>file3      //自定義輸出将标準輸出輸入到檔案file3
echo "hello" >&3
echo "byebye"
ls -a ./hehe      //沒有這個檔案,發生錯誤,會将錯誤資訊列印到file2中
    
    
結果:

tabstop=8root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ./15.sh 
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ls
10.sh  12.sh  14.sh  2.sh  4.sh  6.sh  8.sh  copy         ren.txt  STDOUT
11.sh  13.sh  15.sh  3.sh  5.sh  7.sh  9.sh  CUSTOME_STD  STDERR
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat STDOUT 
byebye
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat STDERR 
ls: cannot access './hehe': No such file or directory
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat CUSTOME_STD 
hello
           

繼續閱讀