shell腳本基礎進階(三)----流程控制語句

流程控制語句apache

控制語句,即用來實現對程序流程的選擇、循環、轉向和返回等進行控制的語句。Bash中的控制語句有幾種控制語句?額,小編也沒統計過,不清楚哎!!按照百度百科的分類(選擇語句,循環語句,轉向語句)總結了幾個。而後看下吧!編程

1、選擇語句centos

一、if……else……fi數組

格式:bash

(1)if CONDITION;then
    if-true-doing
   fi 
(2)if CONDITION;then
    if-true-doing
   else
    if-false-doing
   fi 
(3)if CONDITION;then
    if-true-doing
   elif CONDITION;then
    if-true-doing
   else
    if-false-doing
   fi

注:!CONDITION 條件相反less

練習1:若是某路徑不存在,則將其建立爲目錄;不然顯示其存在,並顯示內容類型ssh

 腳本:if.shtcp

[root@centos bash]# cat if.sh 
#!/bin/bash
#
file=/data/test
if [ -e $file ];then
   echo "$file exists."
   file $file
else
   mkdir -p $file
fi
[root@centos bash]# ./if.sh 
[root@centos bash]# ls -d /data/test
/data/test
[root@centos bash]# ls -dl /data/test
drwxr-xr-x. 2 root root 4096 Sep 19 16:35 /data/test
[root@centos bash]# ./if.sh 
/data/test exists.
/data/test: directory
[root@centos bash]#

練習2:位置參數與命令引用練習,統計用戶任意指定的普通文件的行數ide

[root@centos bash]# cat 1.sh 
#!/bin/bash
if [ -f $1 ];then
 lines=$(wc -l $1|cut -d ' ' -f1) 
 echo "the $1 have $lines lines."
else 
  echo "the $1 is not exists or not a com file."
fi
[root@centos bash]# ./1.sh /etc/grub.conf 
the /etc/grub.conf have 17 lines.
[root@centos bash]# ./1.sh /etc/grub
the /etc/grub is not exists or not a com file.
[root@centos bash]#

練習3:特殊變量$#$@使用,輸出腳本參數信息 模塊化

[root@centos bash]# cat 3.sh 
#!/bin/bash
echo "you input $# parameters."
echo "you input the parameters are $@."
[root@centos bash]# ./3.sh 1 2 3
you input 3 parameters.
you input the parameters are 1 2 3.
[root@centos bash]#

補充知識點:

bash腳本與用戶交互使用的命令read.

    read [options] VAR...

    -p prompt  提示信息

    -t timeout   超時時間

練習4:熟悉read命令的用法,請用戶交互輸入用戶名,並判斷建立系統新用戶

[root@centos bash]# cat read.sh 
#!/bin/bash
read -p "plz input a new username:" -t 10 username
if [ -z $username ];then
  echo "you input empt,the end."
  exit
fi
 
if id $username &> /dev/null; then
  echo "$username exists."
else
  useradd $username
  echo "the new user $username was be added."
fi
[root@centos bash]# ./read.sh 
plz input a new username:
you input empt,the end.
[root@centos bash]# ./read.sh 
plz input a new username:centos
the new user centos was be added.
[root@centos bash]# id centos
uid=500(centos) gid=500(centos) groups=500(centos)
[root@centos bash]# ./read.sh 
plz input a new username:centos
centos exists.
[root@centos bash]#

練習5:判斷給定的兩個數值,孰大孰小;

[root@centos bash]# cat 5.sh 
#!/bin/bash
#
#read -p "plz input two integer:" -t 10 num1 num2
 
if [ $# -lt 2 ];then
  echo "your input parameters are less than 2.plz re-enter."
  exit 1
fi 
 
if [[ $1 =~ ^[0-9]+$ ]]&&[[ $2 =~ ^[0-9]+$ ]];then
   if [ $1 -gt $2 ];then
     echo "the max number is $1."
     echo "the min number is $2."
   else 
     echo "the max number is $2."
     echo "the min number is $1."
   fi
else
   echo "the number $1 or $2 is not a integer.at least have a string."
fi
   
[root@centos bash]# ./5.sh 3 2
the max number is 3.
the min number is 2.
[root@centos bash]# ./5.sh a 4
the number a or 4 is not a integer.at least have a string.
[root@centos bash]# ./5.sh 2
your input parameters are less than 2.plz re-enter.
[root@centos bash]# ./5.sh a
your input parameters are less than 2.plz re-enter.
[root@centos bash]#

二、case

    簡潔版多分支if語句,當if語句中有多個elif時可使用case語句代替,語言更簡潔容易理解。使用場景:判斷某變量的值是否爲多種情形中的一種時使用;

格式:

case $VARIABLE in 
    PATTERN1)
    分支1
    ;;
    PATTERN2)
    分支2
    ;;
    PATTERN3)
    分支3
    ;;
    ...
    *)
    分支n
    ;;
esac

PATTERN可以使用glob模式的通配符:

    *: 任意長度的任意字符;

    ?: 任意單個字符;

    []: 指定範圍內的任意單個字符;

    a|b: 多選1

練習6:腳本可接受四個參數

    start: 建立文件/var/lock/subsys/SCRIPT_NAME

    stop: 刪除此文件

    restart: 刪除此文件並從新建立

    status: 若是文件存在,顯示爲"running",不然,顯示爲"stopped" 

#!/bin/bash
file_name=$(basename $0)
pfile="/data/test/$file_name"
 
if [ $# -lt 1 ];then
  echo "Usage: $0 start|stop|restart|status."
fi
 
case $1 in
  start)
    touch $pfile
    if [ -f $pfile ];then
      echo "$file_name was started."
    else
      echo "$file_name start failed."
    fi
    ;;
  stop)
    rm -f $pfile
    if [ -f $pfile ];then
     echo "$file_name stop failed."
    else
     echo "$file_name was stoped." 
    fi
    ;;
  restart)
    if ! [ -f $pfile ];then
     echo "$file_name is not running." 
    else
      rm -f $pfile
      if [ -f $pfile ];then
       echo "$file_name restart failed."
      else
       touch $pfile
       if [ -f $pfile ];then 
        echo "$file_name was restarted."
       else 
        echo "$file_name restart failed."
       fi
      fi
    fi
    ;;
  status)
    if [ -f $pfile ];then
      echo "$file_name is running."
    else 
      echo "$file_name is stop."
    fi
    ;;
  *)
   echo "Usage: $0 start|stop|restart|status."
   ;; 
esac

2、循環語句

一、for……do……done

格式:

1)、for CONDITION;do

doing-loop

      done

    condition是決定for循環的次數,運行和退出循環的條件。他的形式有多種樣式,下面是列舉的幾種類型:

一、List:能夠羅列出變量具體的取值範圍,枚舉。例:

    name  in user1,user2,user3,user4

二、命令引用:若是是連續的數字能夠引用命令seq,這裏也能夠是其餘可以取出一組數據的命令。例:

    i  in `seq 1 100`

整數數字還能夠寫成{1...100},與seq命令效果相同。

三、還能夠是已經定義好的數組,例:

    a=(1,3,4,5,6,7)

        i in ${a[*]}

四、或者取某一範圍的值,例:

   file in /var/log/*

練習7:求100之內全部偶數之和; 

[root@centos bash]# ./6.sh 
2550
[root@centos bash]# cat 6.sh 
#!/bin/bash
declare -i sum
for i in `seq 0 2 100`;do
  sum+=$i
done 
echo $sum
[root@centos bash]#

[root@centos bash]# cat 6.sh 
#!/bin/bash
declare -i sum
for i in {1..100};do
  if [ $[$i%2] -eq 0 ];then
    sum+=$i
  fi
done
 
echo $sum
[root@centos bash]# ./6.sh 
2550
[root@centos bash]#

練習8:顯示/etc目錄下全部普通文件列表,然後統計一共有多少個文件 

[root@centos bash]# cat 7.sh 
#!/bin/bash
declare -i conut=0
for file in /etc/*;do
   if [ -f $file ];then
let conut++
        echo $conut $file
   fi
done
[root@centos bash]# ./7.sh 
1 /etc/adjtime
2 /etc/aliases
……
124 /etc/wgetrc
125 /etc/yp.conf
126 /etc/yum.conf
[root@centos bash]#

練習9:寫一個腳本

    (1) 傳遞兩個文本文件路徑給腳本;

    (2) 顯示兩個文件中空白行數較多的文件及其空白行的個數;

    (3) 顯示兩個文件中總行數較多的文件及其總行數; 

[root@centos bash]# cat 8f.sh 
#!/bin/bash
space_lines1=$[$(grep '^$' $1|wc -l)+$(grep '^[[:space:]]\+$' $1|wc -l)]
space_lines2=$[$(grep '^$' $2|wc -l)+$(grep '^[[:space:]]\+$' $2|wc -l)]
 
if [ $space_lines1 -gt $space_lines2 ];then
   echo "File $1 have $space_lines1 space lines more than $2."
else
   echo "File $2 have $space_lines2 space lines more than $1."
fi
###############################################################################
file_lines1=$(cat $1|wc -l)
file_lines2=$(cat $2|wc -l)
if [ $file_lines1 -gt $file_lines2 ];then
    echo "File $1 have $file_lines1 lines more than $2."
else
    echo "File $2 have $file_lines2 lines more than $1."
fi
 
[root@centos bash]# ./8f.sh 5.sh 6.sh 
File 5.sh have 3 space lines more than 6.sh.
File 5.sh have 21 lines more than 6.sh.
[root@centos bash]#

練習10:寫一個腳本,打印九九乘法表;

[root@centos bash]# cat 9.sh 
#!/bin/bash
for i in {1..9};do
  for j in $(seq 1 $i);do
    if ! [ $i -eq $j ];then
       echo -n -e "${j}X${i}=$[$i*$j]\t"
    else
       echo -e "${j}x${i}=$[$i*$j]\t"
    fi
  done
done
[root@centos bash]# ./9.sh 
1x1=1
1X2=2 2x2=4
1X3=3 2X3=6 3x3=9
1X4=4 2X4=8 3X4=12 4x4=16
1X5=5 2X5=10 3X5=15 4X5=20 5x5=25
1X6=6 2X6=12 3X6=18 4X6=24 5X6=30 6x6=36
1X7=7 2X7=14 3X7=21 4X7=28 5X7=35 6X7=42 7x7=49
1X8=8 2X8=16 3X8=24 4X8=32 5X8=40 6X8=48 7X8=56 8x8=64
1X9=9 2X9=18 3X9=27 4X9=36 5X9=45 6X9=54 7X9=63 8X9=72 9x9=81
[root@centos bash]#
簡化
#!/bin/bash
for i in {1..9};do
  for j in $(seq 1 $i);do
       echo -n -e "${j}X${i}=$[$i*$j]\t"
  done
    echo 
done

二、while/do……while

格式:

while CONDITION; do

    循環體

    控制變量的修正表達式

done


進入條件:當CONDITION爲「真」;

退出條件:當CONDITION爲「假」;

練習11:分別求100之內全部奇數之和,及全部偶數之和 

[root@centos bash]# cat 11.sh 
#!/bin/bash
declare -i sum=0
declare -i sum_1=0
declare -i sum_2=0
declare -i i=1
while [ $i -le 100 ];do
  if [ $[$i%2] -eq 0 ];then
    sum_1+=$i
  else
    sum_2+=$i
  fi
   sum+=$i
   let i++
done
  echo "the sum of numbers in 100 is $sum."
  echo "the sum of odd numbers in 100 is $sum_1."
  echo "the sum of even numbers in 100 is $sum_2."

三、Until

格式:

until CONDITION; do

    循環體

循環控制變量的修正表達式

done

 

進入條件:當CONDITION爲「假」時

退出條件:當CONDITION爲「真」時

練習12:分別使用whileuntil循環實現添加10個用戶:user1-user10 

[root@centos bash]# cat 12.sh 
#!/bin/bash
declare -i i=1
until [ $i -eq 11 ];do
  useradd user$i
  let i++
done
[root@centos bash]# tail /etc/passwd
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
saslauth:x:498:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
centos:x:500:500::/home/centos:/bin/bash
[root@centos bash]# chmod +x 12.sh 
[root@centos bash]# ./12.sh 
[root@centos bash]# tail /etc/passwd
user1:x:501:501::/home/user1:/bin/bash
user2:x:502:502::/home/user2:/bin/bash
user3:x:503:503::/home/user3:/bin/bash
user4:x:504:504::/home/user4:/bin/bash
user5:x:505:505::/home/user5:/bin/bash
user6:x:506:506::/home/user6:/bin/bash
user7:x:507:507::/home/user7:/bin/bash
user8:x:508:508::/home/user8:/bin/bash
user9:x:509:509::/home/user9:/bin/bash
user10:x:510:510::/home/user10:/bin/bash
[root@centos bash]#

四、循環控制:

continue [n]:提早結束本輪循環,而直接進入下一輪;

break [n]:提早結束循環;

五、死循環:

    始終知足執行條件,沒法退出循環。這樣的循環內,可使用循環控制來跳出循環。

格式:

(1)while true; do

        循環體

     done 

(2)until false; do

        循環體

     done


六、特殊的循環用法:

(1)while遍歷文件的每一行

    while read VARIABLE; do

        循環體

    done < /PATH/FROM/SOME_FILE

(2)For循環類C++用法

for ((expr1;expr2;expr3)); do

    循環體

done

練習13:傳遞一個文本文件爲參數給腳本,取出此文件的全部的偶數行給予顯示,行前要顯示行號;

[root@centos bash]# cat 13.sh 
#!/bin/bash
grep -n '.' $1|cut -d: -f1|while read line_nu;do
   line=`sed -n "${line_nu}p" $1`
   if [ $[$line_nu%2] -eq 0 ];then
   echo $line_nu $line
   fi
done
[root@centos bash]# ./13.sh 12.sh 
2 declare -i i=1
4 useradd user$i
6 done
[root@centos bash]#

3、函數

 把一段具備獨立功能代碼封裝在一塊兒,並給予命名;後續用到時,可直接經過給定函數名來調用總體代碼;

函數做用:一、代碼重用;二、模塊化編程

函數的使用方法:

    先定義:編寫函數代碼

    後調用:給出函數名,還可按需傳遞參數

定義方法:

(1) function f_name {

        函數體

    }

(2) f_name() {

        函數體

    }

調用函數:

f_name [argu1, argu2, ...]

自定義函數狀態返回值:

return [#]

    0: 成功

    1-255:失敗

注意:函數代碼執行時,一旦遇到return,函數代碼終止運行,函數返回;

相關文章
相關標籤/搜索