您的位置:首页 > 运维架构 > Shell

shell学习之-程序的流程控制(1)

2007-10-15 16:40 656 查看
shell编程学习
2
3  1, shell程序的流程控制
4
5  **条件测试语句if then fi
6  全部的基本形式为:
7
8  if xxxx; then
9      xxx
10  elif xxx; then
11      xxx
12  elsif xxx; then
13      xxx
14  else
15      xxx
16  fi
17
18  条件语句有两种编写形式:
19  *if xxx
20  then
21      xxx
22  fi
23
24  *if xxx; then
25      xxx
26  fi
27
28  (1)简单的if then fi
29
30  *******
31  if [ "10" < "12" ]; then
32      echo "yes"
33  fi
34  *******
35  注意:这里的if和[间有一空格,参数和[间也有一个空格。而;和then间可以没有空格,表示继续执行后面的语句;
36
37  (2)变量测试
38  具体的变量测试的语法和比较的关键字,可以使用 man test 进行查询
39
40  *****
41  #!/bin/sh
42  #testvar.sh
43
44  echo "please input you name :"
45  read NAME
46
47  if [ "$NAME" = "" ]; then
48      echo "you name is null"
49  elif [ "$NAME" = "hover" ]; then
50      echo "haha, It's me"
51  else
52      echo "You name is ${NAME}, welcome!"
53  fi
54
55  exit
56  *****
57  小结:当变量中含有空格或TAB时,必须用引号引起来。所以如果对变量进行测试,一般是要用引号引起来的。
58
59  (3)对执行语句进行测试
60
61  *****
62  #!/bin/sh
63  #test-express.sh
64
65  echo "iput a string:"
66  read STR
67
68  if echo "$STR" | grep 'hover' &>/dev/null
69  then
70      echo "haha, I am here, I am ${STR}"
71  else
72      echo "I am not here"
73  fi
74
75  exit
76  *****
77  小结:
78  *这里测试的表达是可以多种多样,而且可以测试与和或的表达式,具体的语法可以man test 进行查看。
79  *在进行语句的测试时,如果需要避免错误信息或输出信息,需要用到重定向,具体的专门有专题讲解。
80
81  (4)测试传递的参数
82
83  *****
84  #!/bin/sh
85  #test-invar.sh
86
87  #test paramter which user input
88
89  printusage()
90  {
91      echo "usage : $0 [start|stop|restart]"
92  }
93
94  if [ $# -ne 2 ]; then
95      printusage
96  elif [ "$1" = "" ]; then
97      printusage
98  elif [ "$1" = "start" ]; then
99      echo "start $0"
100  elif [ "$1" = "stop" ]; then
101      echo "stop $0"
102  elif [ "$1" = "restart" ]; then
103      echo "restart $0"
104  else
105      printusage
106  fi
107
108  exit
109  *****
110  小结:和C一样,shell编程中也可以传递参数。其中,$0 $1 ..$n 分别表示参数的第0个第1个第n个值。$#表示参数的个数。
111
112  (5) : null参数
113      : 表示true , 也表示什么都不做
114
115  *****
116  if [ -z "`ls $1`" ]
117  then :
118  else
119      echo "not zero"
120  fi
121
122  *****
123
124  (6) 多个if 的流程控制
125
126  *****
127  #!/bin/sh
128  #mut-if.sh
129
130  #测试使用多个if的情况
131  if [ -z $HH ]; then
132      echo "do you want to set HH"
133      echo "enter [y/n]"
134      read Y_N
135
136      #now set HH
137      if [ "$Y_N" = "y" ] || [ "$Y_N" = "Y" ]
138      then
139          echo "please input value :"
140          read HH
141          if [ -z $HH ]
142          then :                 #HH is null do nothing
143          else
144              echo "now HH=${HH}"
145          fi
146      else
147          HH=hover
148          echo "no, then use default: $HH"
149      fi
150
151  else
152      HH=hover
153      echo "default value is $HH"
154  fi
155
156      echo "last HH=${HH}"
157      unset HH
158      echo "HH unseted, test finished"
159  exit
160
161  *****
162
163  总结: if流程基本上就这么多,具体的用法要根据实际情况进行灵活应用。
164
165
166  2,case 语句
167  case 一种多开关语句,在测试具有多种值的变量时比if语句灵活。
168  使用模式为:
169  case 值 in
170      模式1)
171          命令1
172      ;;
173      模式2)
174          命令2
175      ;;
176      *)
177      命令n
178  esac
179
180  case先取值(记住取值的后面必须要有一个in),然后依次进行匹配模式n :
181  如果有一个模式匹配,则执行相应的命令n,遇到;;结束,退出case语句。
182  如果都不匹配,可以使用*来捕获该值,并从新接受输入。
183
184  (1)简单的case应用
185  *****
186  #!/bin/sh
187  #test-case.sh
188
189  echo "input a number: "
190  read NUM
191
192  case $NUM in
193  1) echo "111"
194      ;;
195  2) echo "22"
196      ;;
197  3) echo "33"
198      ;;
199  *)
200      echo "no match"
201  esac
202  *****
203
204  小结:这里只简单的使用了数字来进行测试,发散一下,如果是单词或多个单词,又该如何呢?
205
206  (2)模式和多模式匹配的应用
207
208  *****
209  #!/bin/sh
210  #test-case1.sh
211
212  echo "Do you want to continue? [y/n|yes/no]"
213  read ANS
214
215  case $ANS in
216  y|Y|yes|Yes|YES)
217      echo "you can continue"
218      ;;
219  n|no|No|NO)
220      echo "you stop"
221      ;;
222  *)
223      echo "your input is wrong"
224
225  esac
226
227  *****
228
229  小结:在匹配多模式时,模式可以以|链结表示“或”的意思。这样就可以进行多模式的匹配了。
由于是单模式的匹配,所以不存在“与”的模式。
230
231  (3)测试命令参数
232
233  *****
234  #!/bin/sh
235  #test-case1.sh
236
237  if [ "$#" -ne "1" ]; then
238      echo "please input one of [start|stop|restart]"
239      exit 1
240  fi
241
242  VAR=$1
243  case $VAR in
244      start)
245          echo "sart ... `basename $0`"
246          ;;
247      stop)
248          echo "stop ... `basename $0`"
249          ;;
250      restart)
251          echo "restar ... `basename $0`"
252          ;;
253      *)
254          echo "input is wrong"
255          ;;
256  esac
257
258  *****
259
260  小结:先要对用户是否出入了命令参数进行检查,然后把第一个参数赋值给一个变量,然后进行处理。
261
262  3,for 循环语句
263  ==============
264
265  for 循环语句的基本形式为:
266      for arg [list]
267      do
268          命令
269      done
270
271  或
272      for arg [list]; do
273          命令
274          ...
275      done
276
277  注意:在循环的每次执行中,arg将顺序的存取list中列出的变量.
278  list中的参数允许包含通配符.
279
280  (1)简单的for程序
281
282  *****
283  #!/bin/sh
284  #test-for.sh
285
286  #测试for语句
287
288  for loop in 1 2 3 4 5 6
289  do
290      echo $loop
291  done
292
293  *****
294
295
296  *****
297  #!/bin/sh
298  #test-for1.sh
299
300  ll="a b c d e"
301  for loop in $ll
302  # for loop in "$ll"
303  do
304      echo $loop
305  done
306
307  *****
308
309  注意:in $ll 和 in "$ll"的区别。前面是简单的替换,没有屏蔽空格,而后面才是完整的变量使用。
310
311  (2)在[list]中使用通配符
312
313  *****
314  #!/bin/sh
315  #test-for2.sh
316
317  #list all file in local dir
318
319  for t_dir in *
320  do
321      echo "$t_dir"
322  done
323
324  echo "=====list file whose name begin with j or s in local dir====="
325  for t_dir1 in [ts]*
326  do
327      echo "$t_dir1"
328  done
329
330  *****
331
332  (3)使用命令替换[list]
333
334  ######
335  #!/bin/bash
336  #  for-loopcmd.sh: 带[list]的for循环
337  #+ [list]是由命令替换产生的.
338
339  NUMBERS="9 7 3 8 37.53"
340
341  for number in `echo $NUMBERS`  # for number in 9 7 3 8 37.53
342  do
343    echo -n "$number "
344  done
345
346  echo
347  exit 0
348  #####
349
350
351  (4)在命令行使用参数
352      如果in [list]的值为空,那么默认的是使用参数传给for循环。
353
354  #####
355  for ll
356  do
357      echo $ll
358  done
359  #####
360
361
362  4 until 循环结构(用的不多)
363  ===================
364  这个结构在循环的顶部判断条件,并且如果条件一直为false那就一直循环下去.(与while基本格式相反)
365
366      until 条件
367          命令1
368          ...
369      done
370  注意:条件可以为任意测试条件,测试发生在循环末尾。循环至少执行一次。
371
372  #########
373  #!/bin/sh
374  #test-until.sh
375
376  #判断root是否已经登陆
377
378  IS_ROOT=`who | grep root`
379  until [ "$IS_ROOT" ]
380  do
381      sleep 2
382  done
383  echo "root have went in"
384
385  exit
386
387  #########
388
389  5,while 循环结构(比较常用)
390      这种结构在循环的开头判断条件是否满足,如果条件一直满足,那就一直循环下去(0为退出码).
与for循环的区别是,这种结构适合用在循环次数未知的情况下. 其基本的格式如下:
391
392  while [condition]
393  do
394      command...
395  done
396
397  ######
398
399  while [condition]; do
400      command...
401  done
402
403  和for循环一样,如果想把do和条件放到同一行上还是需要一个";".
404
405  (1)简单的while循环
406
407  #########
408  #!/bin/sh
409  #test-while.sh
410
411
412  N=0
413  while [ $N -lt 5 ]
414  do
415      N=$( expr $N + 1 )      #或者N=`expr $N + 1`
416      echo $N
417  done
418
419  #########
420
421  (2)利用while读取文件
422
423  #######
424  #2 : read file using while
425  while read LINE
426  do
427      echo $LINE
428  done < t1.sh
429
430  #######
431
432  注意:在读取文件时,输入的格式最好使用以上的形式,而不要使用
433      cat filename | while read LINE
434  这样可能会出错。
435
436  也可以用多个变量来保存多个域的项目
437  ff.txt
438  1 h
439  2 hh
440  3 hhh
441  4 hhhh
442
443  #####
444
445  while read N NAME
446  do
447      echo $N $NAME
448  done < ff.txt
449
450  #####
451
452  注意:这里使用的默认的IFS,如果要处理用:分隔的项目,可以把IFS设置成:然后再进行处理。
453  如:
454      IFS_BACK=$IFS
455      IFS=:
456      ***
457      ***进行一些操作
458      IFS=$IFS_BACK
459
460
461  (3)统计文件中的记录
462
463  文件ff的内容如下:
464  h1 23
465  h2 34
466  h1 45
467  h2 56
468  h1 87
469  要求计算h1的总和?
470
471  ######
472  #计算文件中的统计项目的总和
473
474  RFILE=ff
475  TOTAL=0
476  CA_NAME="$1"
477
478  echo "$#"
479  if [ "$#" -ne "1" ]; then
480      echo "usage : $0 <name>"
481      exit 1
482  fi
483
484  while read NAME NUM
485  do
486      if [ "$NAME" = "$CA_NAME" ]; then
487          TOTAL=`expr $TOTAL + $NUM`
488      fi
489  done < $RFILE
490
491  if [ "$TOTAL" -eq "0" ]; then
492      echo "$CA_NAME is not exit or $RFILE is worng"
493  else
494      echo "$CA_NAME total is $TOTAL"
495  fi
496
497  ######
498
499  (4)在读文件时忽略特定行
500
501  #remove the commet line
502  re_com()
503  {
504      while read line
505      do
506          case $line in
507          /#*|ITEM|"/n");;   #这里注意
508          *)
509              echo "data: $line"
510          ;;
511          esac
512      done < data.txt
513  }
514
515  6,利用break和continue控制程序的流程
516
517  (1)跳出case
518
519  #!/bin/sh
520  #t_break.sh
521
522  #在死循环中如何跳出
523  while :
524  do
525      echo "please input a number: "
526      read NS
527      case $NS in
528      1|2|3|4|5)
529          echo "great! you entered a number between 1 and 5"
530          ;;
531      *)
532          echo "wrong, good bye!"
533          break;
534          ;;
535      esac
536  done
537
538  而continue 语句和c语言中的continue语句有相同的用法。
539
540  到此流程控制的基本用法就告一段落,而要灵活使用它们需要在实践中练习,练习,再练习。
541
542      下面利用这些东西可以写一个简单的菜单,来给用户提供该系统的运行情况的信息。
就是一个系统状态汇报系统。包括系统的内存使用情况,CPU使用情况,磁盘空间的使用情况,
有哪用户已经登陆到该系统上,系统中有哪些进程,开启了哪些服务,该使用系统及其内核的版本.
第一步只需要把该系统做成单一的程序,而第二部可以使用crond服务作成实时监控定期报警的方式。
543
544
545  7, 如何注释掉一段sh程序
546
547  1)在vi中使用命令: %s/^/#/g
548  2)在要注释的段前后加:
549  <<BLOCK
550  ...
551  BLOCK
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: