shell與其他語言一樣也支持for、while循環
for循環的一般格式如下:
1 #!/bin/sh 2 3 for 變量 in 列表 4 do 5 command 1 6 command 2 7 command 1 8 ......... 9 command n 10 done
列表是一組值(數字、字符串等)組成的序列,每個值通過空格分隔。每循環一次,就將列表中的下一個值賦給變量。
列表也可以是一個文件:
in 列表是可選的,如果不用它,for 循環使用命令行的位置參數。
1 #!/bin/sh 2 3 for line in 1 2 3 4 5 6 7 4 do 5 echo "line is $line" 6 done
結果:
[root@localhost 1st]# sh test.sh
line is 1
line is 2
line is 3
line is 4
line is 5
line is 6
line is 7
下面用for循環讀一個文件:
查看文件內容
1 [root@localhost 1st]# cat test.txt 2 hello 3 wolrd 4 hello 5 shell 6 [root@localhost 1st]#
code:
1 #!/bin/sh 2 3 FILE=./test.txt 4 5 for line in $(<$FILE) 6 do 7 echo "line is: $line" 8 done
Results:
1 [root@localhost 1st]# sh xx.sh 2 line is: hello 3 line is: wolrd 4 line is: hello 5 line is: shell 6 [root@localhost 1st]#
while循環的一般格式如下:
1 while command 2 do 3 4 statement 5 6 done
code:
1 #!/bin/sh 2 3 i=0 4 sum=0 5 while [ $i -le 100 ] 6 do 7 sum=$(($sum + $i)) 8 i=$(($i + 1)) 9 done 10 echo "sum is $sum"
1 [root@localhost 1st]# sh xx.sh 2 sum is 5050 3 [root@localhost 1st]#
if語句的一般格式如下:
1 if ....; then 2 .... 3 elif ....; then 4 .... 5 else 6 .... 7 fi
if 條件語句:
文件表達式:
1 [ -f "somefile" ] : 判斷是否是一個文件 2 [ -x "/bin/ls" ] : 判斷/bin/ls是否存在並有可執行權限 3 [ -n "$var" ] : 判斷$var變量是否有值 4 [ "$a" = "$b" ] : 判斷$a和$b是否相等 5 -r file 用戶可讀為真 6 -w file 用戶可寫為真 7 -x file 用戶可執行為真 8 -f file 文件為正規文件為真 9 -d file 文件為目錄為真 10 -c file 文件為字符特殊文件為真 11 -b file 文件為塊特殊文件為真 12 -s file 文件大小非0時為真 13 -t file 當文件描述符(默認為1)指定的設備為終端時為真
字符串表達式:
[string string_operator string]
這里string_operator可為如下幾種:
1 = 兩個字符串相等。 2 != 兩個字符串不等。 3 -z 空串。 4 -n 非空串
eg:
1 #!/bin/sh 2 3 NUMS="hello" 4 [ $NUMS = "hello" ] 5 6 echo $?
results:
1 [root@localhost 1st]# sh xx.sh 2 0
整數表達式:
1 -eq 數值相等。 2 -ne 數值不相等。 3 -gt 第一個數大於第二個數。 4 -lt 第一個數小於第二個數。 5 -le 第一個數小於等於第二個數。 6 -ge 第一個數大於等於第二個數。
Eg:
1 #!/bin/sh 2 3 NUMS=130 4 if [ $NUMS -eq "130" ]; then 5 6 echo "equal" 7 else 8 echo "not equal" 9 fi
results:
1 [root@localhost 1st]# sh xx.sh 2 equal
下滿貼出一個用shell寫的簡單圖書管理系統:
1 #!/bin/bash 2 #Name:Books Management System(BMS) 3 #Author:DREAM 4 file=books.txt 5 function information 6 { 7 echo "Books Management System(BMS)" 8 echo "---------------------------" 9 echo -e " 1: ADD Books" 10 echo -e " 2: Show Books" 11 echo -e " 3: Select Books" 12 echo -e " 4: Delete Books" 13 echo -e " 5: Exit System" 14 #echo 15 echo "---------------------------" 16 read -p "please input your choice:" num 17 echo 18 19 case "$num" in 20 1) Add 21 ;; 22 2) Show 23 ;; 24 3) Select 25 ;; 26 4) Delete 27 ;; 28 5) exit 29 ;; 30 *) information 31 ;; 32 esac 33 } 34 35 function Add 36 { 37 echo -e "please books information eg:(English 101 Jerry)" 38 echo 39 read -p "please input books name: " books_name 40 read -p "please input books number: " books_num 41 read -p "please input books author: " books_author 42 43 echo -e "$books_name\t$books_num\t$books_author" >>$file && { 44 echo "Add Books success" 45 echo "---------------------------" 46 } 47 if [ $? -ne 0 ] 48 then 49 echo "Add Books failure" 50 fi 51 52 information 53 } 54 55 function Show 56 { 57 echo -e "Bname\tBnum\tBauthor" 58 grep -Ev "^$" $file 59 echo "-----------------------" 60 echo 61 information 62 } 63 64 function Search_menu 65 { 66 echo "-----------------------" 67 echo -e " 1: Search By Bname" 68 echo -e " 2: Search By Bnum" 69 echo -e " 3: Search By Bauthor" 70 echo -e " 4: Eixt Search System" 71 echo 72 echo "-----------------------" 73 } 74 75 function Select 76 { 77 Search_menu 78 read -p "please input your choice:" ch 79 case "$ch" in 80 1) 81 read -p "please input books name: " name 82 echo -e "Bname\tBnum\tBauthor\n-------------------------" 83 awk '{if($1~/^'$name'/) print $0}' $file 84 echo "-------------------------" 85 if [ $? -ne 0 ] 86 then 87 echo "the file no exist" 88 fi 89 ;; 90 2) 91 read -p "please input books number: " num 92 echo -e "Bname\tBnum\tBauthor\n-------------------------" 93 awk -v s=$num '$2==s {print $0}' $file 2>/dev/null 94 echo "-------------------------" 95 if [ $? -ne 0 ] 96 then 97 echo "the file no exist" 98 fi 99 echo $? 100 ;; 101 3) 102 read -p "please input books author: " author 103 echo -e "Bname\tBnum\tBauthor\n-------------------------" 104 awk '{if($3~/'$author'/) print $0}' $file 105 echo "-------------------------" 106 if [ $? -ne 0 ] 107 then 108 echo "the file no exist" 109 fi 110 echo $? 111 112 ;; 113 4) exit 114 ;; 115 *) Select 116 ;; 117 esac 118 echo 119 information 120 } 121 122 function Delete 123 { 124 read -p "please input your want delete boos number:" num 125 sed -i "/$num/d" $file 126 127 if [ $? -ne 0 ] 128 then 129 echo "success failure" 130 fi 131 132 information 133 } 134 135 information
利用popen快速獲取一個shell命令的返回值
優點:避免了生成臨時文件
函數原型:
1 #include <stdio.h> 2 3 FILE *popen(const char *command, const char *type); 4 5 int pclose(FILE *stream);
函數說明:
popen()函數通過創建一個管道,調用fork()產生一個子進程,執行一個shell以運行命令來開啟一個進程。這個管道必須由pclose()函數關閉,而不是fclose()函數。pclose()函數關閉標准I/O流,等待命令執行結束,然后返回shell的終止狀態。如果shell不能被執行,則pclose()返回的終止狀態與shell已執行exit一樣。
type參數只能是讀("r")或者寫("w")中的一種,得到的返回值(標准I/O流)也具有和type相應的只讀或只寫類型。如果type是"r"則文件指針連接到command的標准輸出;如果type是"w"則文件指針連接到command的標准輸入。
command參數是一個指向以NULL結束的shell命令字符串的指針。這行命令將被傳到bin/sh並使用-c標志,shell將執行這個命令。
popen()的返回值是個標准I/O流,必須由pclose來終止。前面提到這個流是單向的(只能用於讀或寫)。向這個流寫內容相當於寫入該命令的標准輸入,命令的標准輸出和調用popen()的進程相同;與之相反的,從流中讀數據相當於讀取命令的標准輸出,命令的標准輸入和調用popen()的進程相同。
返回值:
如果調用fork()或pipe()失敗,或者不能分配內存將返回NULL,否則返回標准I/O流。popen()沒有為內存分配失敗設置errno值。如果調用fork()或pipe()時出現錯誤,errno被設為相應的錯誤類型。如果type參數不合法,errno將返回EINVAL。
下面是使用popen獲取主機中虛擬機個數的范例:
1 #include <stdio.h> 2 #include <string.h> 3 4 int main() 5 { 6 FILE *fp; 7 size_t value = 0; 8 int nums; 9 char cmd[1024] = {0}; 10 int guestnums; 11 12 strcpy(cmd, "virsh list --all | sed -n '3, $p' | grep -v '^$' | wc -l"); 13 14 /*使用popen獲取shell命令返回值*/ 15 if((fp = popen(cmd, "r")) != NULL) { 16 17 if(fgets((char *)&nums, 2, fp)) 18 { 19 guestnums = atoi((char *)&nums); 20 } 21 } 22 23 printf("%d\n", guestnums); 24 pclose(fp); 25 26 return 0; 27 28 }
