shell脚本是一些命令的集合。shell脚本能帮助我们很方便地管理服务器,我们可以指定一个任务计划,定时去执行某个shell脚本以满足需求。
shell脚本通常都以 .sh为后缀名。如图所示,脚本文件first.sh的第1行要以 #!/bin/bash 开头,表示文件使用的是bash语法。#表示注释,后面跟一些该脚本的相关注释内容,以及作者、创建日期或者版本等。
其实shell脚本还有一种执行方法,使用该方法运行shell脚本的前提是脚本本身有执行权限,所以需要给脚本加一个x权限。
另外,使用sh命令执行一个shell脚本时,可以加 -x 选项来查看这个脚本的执行过程,有利于我们调试这个脚本,如图所示。
如果脚本里打错字符,执行命令时会提示你哪行出了错误,然后输入编辑命令的时候,后面+错误的行数,光标会自动跳到错误的行数。(例如,第7行错了,命令:vi first.sh +7)
例如:
定义变量的格式为:“变量名=变量的值”。在脚本中引用变量需要加上符号$。下面编写一个与变量相关的脚本,如图。
上图圈起来的地方为反引号,它的作用时将引号中的字符串当成shell命令执行,返回命令的执行结果。d和d1在脚本中作为变量出现。sleep 2相当于一个定时器,意思就是等待两秒然后返回值。下面来看看该脚本的执行结果,如图。
数学计算要用 [ ] 括起来,并且前面要加符号$。sum=那里不要有空格,不然会出错。该脚本的结果如下:
read命令用于和用户交互,它把用户输入的字符串作为变量值。该脚本的执行过程如下:
有时我们会用到类似 /etc/init.d/iptables restart 的命令,前面的 /etc/init.d/iptables 文件其实就是一个shell脚本。后面为什么可以跟 restart 字符串?这就涉及shell脚本的预设变量。实际上,shell脚本在执行时,后面可以跟一个或者多个参数。例如下面的脚本:
脚本中的$1和$2就是shell脚本的预设变量。本例中,$1和$2的值就是在执行时分别输入的2和4,$1就是脚本的第一个参数,$2就是脚本的第二个参数,当然一个shell脚本的预设变量是没有限制的。
另外还有一个$0,它代表脚本本身的名字。,如图。
if 判断语句;then
command
fi
示例脚本如下:
if1.sh中出现了 ((a<60)) 这样的形式,就是shell脚本中特有的格式,只用一个小括号或者不用都会报错。
该脚本的执行结果如下:
if 判断语句;then
command
else
command
fi
示例脚本如下:
该脚本的执行结果如下:
脚本if2.sh和脚本if1.sh唯一区别是:如果输入大于或等于60的数字会有提示。
if 判断语句1;then
command
elif 判断语句2;then
command
else
command
fi
示例脚本如下:
这里的&&表示 “ 并且 ” 的意思,也可以使用 | | 表示 “ 或者 ”。
该脚本的执行结果如下:
以上只是简单介绍了if语句的结构。判断数值大小除了可以用 (( )) 的形式外,还可以使用 [ ]。但是不能使用>、<、=这样的符号了,要使用 -lt(小于)、-gt(大于)、-le(小于等于)、-ge(大于等于)、-eq(等于)、-ne(不等于)。
示例代码如下:
# a=10; if [ $a -lt 5 ]; then echo ok; fi
# a=10; if [ $a -gt 5 ]; then echo ok; fi
ok
# a=10; if [ $a -ge 10 ]; then echo ok; fi
ok
# a=10; if [ $a -eq 10 ]; then echo ok; fi
ok
# a=10; if [ $a -ne 10 ]; then echo ok; fi
下面是在if语句中使用&&和 | | 的情况,示例代码如下:
# a=10; if [ $a -lt 1 ] || [$a -gt 5 ]; then echo ok; fi
ok
# a=10; if [ $a -gt 1 ] || [$a -lt 10 ]; then echo ok; fi
ok
shell脚本中if还经常用于判断文档的属性,比如判断是普通文件还是目录,判断文件是否有读、写、执行权限等。if常用的选项有以下几个。
使用if判断时的具体格式如下:
if [ -e filename ]; then
command
fi
示例代码如下:
因为/home/是目录而非文件,所以并不会显示ok。其他示例如下所示:
case 变量 in
value1)
command
;;
value2)
command
;;
value3)
command
;;
*)
command
;;
esac
上面的结构中,不限制value的个数,*代表其他值。下面写一个判断输入数值是奇数还是偶数的脚本,如图。
脚本中$a的值为1或0,其执行结果如下:
先写个简单的for循环脚本,如图。
脚本中的seq 1 5表示从1到5的一个序列。该脚本的执行结果如下:
通过这个脚本可以看到for循环二点基本结果,具体格式如下:
for 变量名 in 循环的条件;do
command
done
这里 “循环的条件” 可以是一组字符串或者数字(用一个或者多个空格隔开),也可以是一条命令的执行结果。命令如下:
“循环的条件” 还可以引用系统命令的执行结果(如seq 1 5),但必须用反引号括起来。示例命令如下:
while 条件; do
command
done
示例脚本如下:
该脚本的执行结果如下:
另外,可以用一个冒号代替循环条件,这样可以做到死循环。示例代码如下:
while :; do
command
sleep 3
done
shell脚本中的函数就是先把一段代码整理到一个小单元中,并个这个小单元命名,当用到这段代码时直接调用这个小单元的名字即可。有时候脚本中的某段代码总是重复使用,如果写成函数,每次用到时直接用函数名代替即可。
写个简单的带有函数功能的shell脚本,示例脚本如下:
该脚本的执行结果如下:
func.sh中的sum()为自定义的函数。在shell脚本中函数的格式如下:
function 函数名()
{
command1
command2
}
注意的是,shell脚本中,函数一定要写在最前面,不能出现在中间或者最后。
break用在循环中,不管是for或者while都可以。在脚本中使用它,退出该层循环。之所以说层,是因为有时我们会用到嵌套循环,大循环里面还有小循环,而break仅是退出那一层循环,它的上层循环不受影响。
脚本中,本意是要把1~5数值赋予 i,当 i 等于3时,会跳出循环,后面的4和5都不会再执行,脚本的执行结果如下:
continue也是使用在循环中的,但和break不同的是,当shell脚本中遇到continue时,结束的不是整个循环,而是本次循环。具体示例如下:
脚本执行结果如下:
当 i 等于3时候,出现了continue,所以结束本次循环,continue后面的语句不再执行,继续下一次循环。
exit的用法跟break、continue相似。它的作用范围更大,直接退出整个shell脚本。示例脚本如下: