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
shell学习之-程序的流程控制(1)
最新推荐文章于 2019-08-04 21:10:19 发布