无论多复杂的脚本,都是由一些基本的结构构成的。
下面,介绍一下基本的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
发表回复
要发表评论,您必须先登录。