上篇我们说了关于shell的脚本学习之一——符号问题,有兴趣的同学可以去看看。今天我们来看看shell的语法问题。
1.条件测试
<1>.test / [
在脚本中测试是比较常见,命令test或者[ 可以测试条件是否成立。但值得注意的是,shell和C语言的逻辑表示刚好相反,1表示条件不成立,0表示条件成立。在使用 [ 时,一定要将命令和各个参数用空格隔开。
接下来,我们看一个例子
#############################################
# File Name: test1.sh
# Author: monster
# mail: 1104306242@qq.com
# Created Time: Fri 30 Jun 2017 05:52:58 PM CST
#############################################
#!/bin/bash
val=10
test $val -gt 9
echo $?
test $val -gt 10
echo $?
[ $val -gt 9 ]
echo $?
[ $val -gt 10 ]
echo $?
我们分别用test和[ 进行了测试。结果如下。
区别于C语言的是,这里的>、<、>=、<=、==在shell脚本中分别对应-gt、-lt、-ge、-le和-eq。除了这面的测试,另外也可以测试目录是否存在、两个字符串是否相同等等。同样,也可以把与或非这些逻辑命令运用起来。逻辑非用“!”表示,逻辑与“-a”表示,逻辑或用“-o”表示。
<2>.if/then/elif/else/fi
和C语言相似,在脚本中也是有if、else、then等这些命令的,用来实现分支控制。每当我们使用一条if语句时,在这个if语句表示的逻辑结束时需要用一个fi来表示这个if语句块的结束。如果两条命令写在同一行我们需要用“;”来隔开,如果只有一条就不用写”;”了,但是如果then后面换行了,这条命令并没有写完,shell会自动续行。和 [ 一样,命令需要和参数隔开。下面我们举个例子来说if在shell中怎么用。
#######################################################
# File Name: test1.sh
# Author: monster
# mail: 1104306242@qq.com
# Created Time: Fri 30 Jun 2017 05:52:58 PM CST
#######################################################
#!/bin/bash
echo "plesae enter the number(1-10):"
read number
if [ $number -ge 5 ];then
echo "the number >= 5"
elif [ $number -lt 3 ];then
echo "the number < 3"
else
echo "the number ==4"
fi
测试结果如下图。从上面的代码来看,其实和我们学习的C语言区别不是很大。
在if语句中也可以运用“&&”和“||”,但是需要注意,“&&”相当于“if…then…”,而“||”相当于“if not…then…”。在这里不管是“&&”还是“||”都是用于连接两个命令,而在上面我们说了”-a“和”-o“,这两个是用来连接测试条件的,一定要注意区别。例如。
#!/bin/bash
echo "plesae enter the number(1-10):"
read number
[ $number -ge 5 ] &&{
echo "the number >=5"
}
[ $number -lt 5 ] || {
echo "the number >=5"
}
这两条语句效果是一样的,都是用来判断数字是否大于等于5。如果比5小,则什么都不输出 。
<3>.case /esac
case语句就和我们C语言学习的swith/case语句是相似的,但这里用esca来表示case语句逻辑的结束。在C语言中,case只能匹配整型或者字符型常量表达式,而shell脚本中case可以匹配字符串和通配符,每个分支可以有多个命令,末尾必须以“;;”结束。执行的时候找到第一个匹配的分支并且执行完相应的命令后,就会直接跳转到esca之后,不需要像C语言一样用break跳出。例如。
echo "please enter the char(a-d):"
read char
case $char in
a )
echo "the char is a"
;;
b )
echo "the char is b"
;;
c )
echo "the char is c"
;;
d )
echo "the char is d"
;;
esac
2.循环语句
<1>.for / do /done
在shell脚本中的for循环和C语言的还是有比较大的区别的。在这里不做说明,我们直接上例子看。
#######################################################
# File Name: for.sh
# Author: monster
# mail: 1104306242@qq.com
# Created Time: Sat 01 Jul 2017 10:08:00 AM CST
#######################################################
#!/bin/bash
for i in {a..d}
do
echo "printf val is :$i"
done
在这里我们做得是循环打印出a-d每个字符。除了这种写法,我们还可以用下面这种方式。结果如愿打印出1-5。
for ((i=0;i<=5;i++))
do
echo "printf val is :$i"
done
<2>.while / do /done
当然说到了循环,肯定少不了while,while在脚本中的用法是和C语言比较相像的。举个例子,循环打印出0-6。
i=0
while [ $i -le 6 ]
do
echo $i
let i++
done
shell中的until和C语言也是类似的,until表示知道条件不成立,否则一直执行。在这里就不举例子说明了。
3.位置参数和特殊变量
在shell中有很多特殊变量是被shell自动赋值的,在这里我们来总结一下位置参数和特殊变量有哪些。
1. $ 0
相当于C语言中main函数的argv[0]
2. $1、$2…
相当于C语言中main函数的argv[1]、argv[2]……
3. $#
表示的是命令行参数的个数
4. $@
表示参数列表$1、$2……可以用在for循环中in的后面
5. $?
存储上一条命令的退出码
6. $$
当前shell的进程号
下面我们举例如何使用这些特殊的位置参数和特殊变量。
for i in $@
do
echo $i
done
echo "the total:$#"
、
很明显我们是把从命令行输入的数据打印出来,并打印参数的个数。在这里,单独说一个“shift n”,它表示把命令参数向左移动,从$1开始。
4.函数
说了这么多,我们还没有说shell中的函数的语法是什么。函数在C语言和shell中大多数是一样,但还是有几点区别的。
- shell脚本中无论函数有没有参数,在编写函数的时候没有参数列表。
- shell脚本中的函数没有类型的区分,用”function”,也可写可不写。
- 在调用函数的时候,如果有参数直接在后面写出。在这里函数就相当于一条命令,所以调用的时候格式如同命令。
- 注意函数体的左花括号{和后面的命令之间必须是有空格或者换行的,如果将最后一条命令和右花括号}写在了同一行,命令行末必须有“;”号。
- 不允许出现空的代码块。如果什么都不做,可以用;在代码块的内部。
下面举个例子来对上面说得内容进行解释。
function maxmin(){
max=$1
min=$1
for i in $@
do
[ $max -le $i ] &&{
max=$i
}
[ $min -gt $i ] &&{
min=$i
}
done
echo "max=$max"
echo "min=$min"
}
maxmin "$@"
我们用函数来对命令行输入的参数进行大小比较,找出最大的和最小的。shell中的脚本都是先定义再调用,所以一般把函数的定义写在前面,把对脚本的调用和其他命令写在后面。另外,shell函数没有参数列表并不能表示不能传参数,而是对函数来说,调用时可以传任意个参数,而且在这里函数就相当于与一个命令,所以会用$1…这些来提取参数的。
5.数组
bash支持一维数组,并且没有限定数组的大小。类似C语言,数组的下标也是从0开始的。在shell中是用括号来表示数组,数组的元素中间是用”空格”分割隔开的。举个例子。
myarr=(1 2 3 4)
for ((i=0;i<4;i++))
do
echo ${myarr[i]}
done
echo "#############"
echo ${myarr[*]}
访问数组的元素时,可以通过for循环,也可以用通配符。
6.shell脚本的调试
说了这么多语法,一直没说如何调试shell脚本。其实shell本身已经提供了一下关于调试脚本的选项。我们说两个最最常见的。
- -n
读一遍脚本的命令,但是不执行。 - -x
跟踪执行信息,将执行的每一条命令和结果依次打印出来。
使用这些选项,我们有三种方法。
1. 在命令行提供参数
2. 在脚本开头提供参数
3. 在脚本中用set启用或禁用参数
下面我们来使用其中一个。
sum=0
for ((i=0;i<5;i++))
do
let sum+=i
done
echo "sum=$sum"
可以从图片中看出shell对每一次循环就进行了显示,在这里循环了五次,最后一次i=5就退出了。有兴趣的同学可以将这三种方法都尝试下。
到这里shell脚本的语法就说完了,下一篇我们来讲讲shell中正则表达式的相关知识。