Shell脚本基本结构-if, case, do, while, until

Shell Liemer_Lius 1373℃ 0评论

无论多复杂的脚本,都是由一些基本的结构构成的。

下面,介绍一下基本的shell脚本语法,快速浏览,来秒熟悉基本的脚本编程结构。

1、单行模式下的脚本逻辑

# [ ! -e /vat/tmp/a.txt ] && touch /vat/tmp/a.txt
# [ -e /vat/tmp/a.txt ] || touch /vat/tmp/a.txt

特点:关键词少,在一行中即可完成,逻辑分明,可以复合使用,&&和||自左到右分别判断来完成逻辑。

2、单分支if语句

#!/bin/bash
#
if [ $# -lt 1 ]; then
  echo "An argument is needed. Exit"
  exit 4
fi

特点:通常是一个开关,满足条件的时候,可以结束脚本,顺利通过判断才能进行到下一步;或者在某些特定的条件的时候才执行的语句,用于特定的操作等。

3、双分支的if语句

#!/bin/bash
#
if [ $1 == '--help' ]; then
  echo "Usage: `basename $0` --help"
else
  echo "Wrong options..."
fi

特点:用于两种情况的判断,更多的条件就不支持了。

4. 多分支的if语句

#!/bin/bash
# Usage:
# Author: Liemer_Lius
if [ $1 == '--del' ]; then
  echo "Delleting..."
elif [ $1 == "--add" ]; then
  echo "Adding..."
elif [ $1 == "--help" ]; then
  echo "Usage: ..."
else
  echo "Wrong options..."
fi

[root@rs1 ~]# ./i.sh --add
Adding...
[root@rs1 ~]# ./i.sh --del
Delleting...
[root@rs1 ~]# ./i.sh --help
Usage: ...
[root@rs1 ~]# ./i.sh --helppp
Wrong options...

特点:可以处理比较复杂的条件,但case显然更适合这样的场景。

5、case判断

#!/bin/bash
# Usage:
# Author: Liemer_Lius
case $1 in
[0-9])
  echo "Digit.";;
[[:alpha:]])
  echo "alpha";;
*)
  echo "punct..."
esac

特点:case专门供选项多的脚本进行参数的判断,有了它,多参数可以轻松编辑进入脚本的控制条件,实现快速定位和执行相应命令。

case的每个语句中,只有最后一个语句可以不加双引号,双引号可以换行加,更加美观。

6. do循环

#!/bin/bash
# Usage:
# Author: Liemer_Lius
for i in {1..10}; do
  echo -n "$i,"
done
echo
for j in $(seq 2 2 24); do
  echo -n "$j,"
done
echo
for k in {hello,world,i,am,who,i,am}; do
  echo -n "$k,"
done
echo
[root@rs1 ~]# ./j.sh 
1,2,3,4,5,6,7,8,9,10,
2,4,6,8,10,12,14,16,18,20,22,24,
hello,world,i,am,who,i,am,

特点:用于有限次数的循环,通常用{1..9}(表示1-9),$(seq 10)(seq的命令结果引用)来实现次数的限制,也可以用一个{a,b,c,d}这种类型的列表来做为选择(用于选项少的情况)。

7、while循环

# 一般用法
#!/bin/bash
# Usage:
# Author: Liemer_Lius
declare -i I=0
while [ $I -le 10 ]; do
  echo -n "$I,"
  let I+=1
done
echo

[root@rs1 ~]# ./k.sh     // 执行脚本
0,1,2,3,4,5,6,7,8,9,10,

# 常用关键词:continue,break
#!/bin/bash
# Usage:
# Author: Liemer_Lius
declare -i I=0
while [ $I -le 10 ]; do
  if [ $I -eq 3 ]; then
    let I=$[$I+1]
    continue
  elif [ $I -eq 9 ]; then
    break
  else
    echo -n "$I,"
  fi
  let I=$[$I+1]
done
echo 'Finished'

[root@rs1 ~]# ./l.sh     // 执行脚本
0,1,2,4,5,6,7,8,Finished

# 与read的联用
#!/bin/bash
# Usage:
# Author: Liemer_Lius
cut -d: -f1 /etc/passwd |head > a.txt
while read USER; do
 echo "Hello, $USER..."
done < a.txt

[root@rs1 ~]# ./q.sh     // 执行结果
Hello, root...
Hello, bin...
Hello, daemon...
Hello, adm...
Hello, lp...
Hello, sync...
Hello, shutdown...
Hello, halt...
Hello, mail...
Hello, uucp...

特点:while循环很容易产生死循环,这时候bash -x也不好看到循环的错误,因为根本停不下来。所以,while循环的开关尤为重要。

continue关键词是跳过本次循环,进入下一个循环;

break是彻底退出循环,但是还执行循环之外的语句;

exit是退出脚本。

上面脚本中,$I=3的时候,单独对$I做了一个赋值,如果没有这个赋值,continue跳出本步循环后,I会一直等于3,进入死循环;

# wihle循环一直为真的判断条件列举:

while :; do                // 很多时候,用冒号来表示True的时候
  echo "Hello..."
  sleep 1
done
[root@rs1 ~]# ./m.sh 
Hello...
Hello...
^C

sum=0                      // 用大小表达式的时候,用双括号
i=1
while (( i <= 100 ))
do
 let "sum+=i"
 let "i += 2"
done
echo "sum=$sum" 

#!/bin/bash                // while、do的循环条件,可以写在一行,用(())来实现,[]和[[]]不可以。
# Usage:
# Author: Liemer_Lius
#!/bin/bash 
sum=0
for(( i = 1; i <= 100; i = i + 2 )); do
let "sum += i"
done
echo "sum=$sum" 
[root@rs1 ~]# ./r.sh 
sum=2500

注意:当用(())的时候,里面的内容才可以用<>-+=等直接处理,且变量不用加$符号。如果是[]或[[]],则只能使用-eq, -le等类型的英文表达方法。

8、until循环

#!/bin/bash
# Usage:
# Date: 2017-12-12
# Author: Liemer_Lius
declare -i SUM=0
declare -i I=0
until [ $I -gt 100 ]; do
  let "SUM+=I"
  let I+=1
done
echo "Summary: $SUM"

[root@rs1 ~]# ./s.sh              // 执行结果
Summary: 5050

特点:和while一样,需要一个判断开关,和一个不断变换参数值的语句,否则容易陷入死循环。

9、shift的用法

shift是切换$[1-9]变量的,例如,脚本中可以只有$1,利用shift来实现$#里面的选项切换。

#!/bin/bash
# Usage of shift.
for i in {1..3}; do
  echo $1
  shift
done
# bash switch.sh First Second Third
First
Second
Third

10、break,continue的用法

见第7部分,while循环的例子。

break:退出整个循环;

continue:退出本步循环;

exit:退出脚本;

11、return、exit的用法

return是在一定的条件下,返回一个执行状态值,无论返回的是什么,改段代码都停止执行,一般常用与函数中,做为其他代码的判断条件。

exit后面可以跟一个返回值。exit以后,整个脚本退出,如果后面没有返回值的时候,默认将最后一条执行命令的返回值做为exit以后的返回值。

# Usage of ruturn
function COMELE {
  for J in `seq 0 $[${#ARRAY[@]}-1]`; do
    if [ $1 -eq ${ARRAY[$J]} ]; then
      return 1
    fi
  done
  return 0
}

如上,我么定义了一个函数。当引用函数的时候,需要函数判断的那个值($1,函数名后的第一个参数)如果等于数列中的任意一个值的时候,都返回1;如果循环结束以后没有匹配到,则最后还有一个返回0的操作。这个返回值将作为后续代码的判断条件。

# Usage of "exit"
case $1 in
-a|--add)
echo "Adding..."
;;
-d|--del)
echo "Deleting..."
;;
-h|--help)
echo "Usage: `basename $0` -a|--add|-d|--del|-h|--help"
exit 0
;;
*)
echo "Usage: `basename $0` -a|--add|-d|--del|-h|--help"
exit 8
;;
esac

如上,在-h|–help的时候,exit的返回值是0,这表示正常退出,因为参数是正确的;而*)的时候,表示参数写的不正确,这时候exit以后赋予的返回值是8,表示是错误退出。

 

转载请注明:liutianfeng.com » Shell脚本基本结构-if, case, do, while, until

喜欢 (0)

发表回复