创建shell脚本
shell脚本的后缀名是.sh。下面是一个简单脚本的创建:
用vim打开脚本,可以看到里面就一句简单的echo指令:
shell脚本实际上就是各种linux指令和工具使用的集合。
通常,在脚本的最开始会指明使用哪个shell来执行该脚本,因此会有#!/bin/bash这样的语句。改写上例:
此外,脚本可以有返回值,使用exit x的命令,x就是返回值:
通常返回0表示脚本运行正常,否则表示异常。
调用完shell脚本后,可以通过$?来查看脚本是否运行正常:
shell脚本如果不指定exit,那么就默认返回最后一条指令的退出状态。
以上就是一个最基础的脚本。
注释
先提一下注释。
前面的例子中,有用到#,它其实是单行注释的符号,但是有一个例外,就是用在第一行的#!/bin/bash中。
对于多行的注释,使用<<!和!配对使用。
参数
shell脚本可以带参数,执行时的形式如下:
查看脚本:
使用$后接数字来表示参数,其中:
$0表示程序名称,$1表示第一个参数,$2表示第二个参数,以此类推。
但是有一点需要注意,当参数个数是两位数时,比如10,则需要将10用{}括起来表示参数,即${10}表示第十个参数,下面是一个例子:
如果写成了$10,得到的结果是错的:
还有几个以$开头的变量与参数有关:
- $@:表示所有参数,每一个参数都是独立的字符串。
- $*:也表示所有参数,但是所有参数都在一个字符串中。
- $#:命令行参数的个数,不包括程序名。
下面是一个例子:
执行下面的命令,得到的结果:
变量
变量有两种,一个是环境变量,一个是用户自定义变量。
环境变量一般用大写,用户变量一般用小写。
变量用$来读取。
以下是一个环境变量:
以下是一个用户变量:
在shell脚本中有一个比较重要的作用,就是将linux命令的执行结果赋值给变量,可以使用反引号来完成:
变量赋值需要注意一点,在变量,等号和值之间不要有空格。
当将一个数学表达式赋值给变量时,可以使用$[ ],下面是一个例子:
脚本结构化
if-then语句
if command
then
commands
elif command
then
commands
else
commands
fi
这里的command的返回值如果是0,就会执行底下的语句。
command可以是单个的,也可以是多个command进行“与”或者“或”,比如下面的例子是判断脚本是否外带参数以及参数的值是否是“all”:
if [ -n $1 ] && [ "$1" = "all" ]
then
xxx
fi
if后接的command,必须有返回值,但是如果没有的话,就不能直接使用。
不过有一个命令test,只要在test后列出的条件成立,test命令就会返回0。
不过对于test命令,有一种更简单的写法:
if [ condition ]
[ ]里面可以进行三种类型的条件判断:
1)数值的比较,下面是一个例子:
[]中使用了-eq,表示两个参数相等。
另外还有其它的比较选项:
比较 | 描述 |
n1 -eq n2 | 检查n1是否与n2相等 |
n1 -ge n2 | 检查n1是否大于或等于n2 |
n1 -gt n2 | 检查n1是否大于n2 |
n1 -le n2 | 检查n1是否小于或等于n2 |
n1 -lt n2 | 检查n1是否小于n2 |
n1 -ne n2 | 检查n1是否不等于n2 |
2)字符串的比较,下面是一个例子:
[]中使用了=来比较,需要注意点,一般数值上才用=这样的符号,而这里字符串上使用了=。
另外还有其它的比较选项:
比较 | 描述 |
str1 = str2 | 检查str1是否和str2相同 |
str1 != str2 | 检查str1是否和str2不同 |
str1 < str2 | 检查str1是否比str2小 |
str1 > str2 | 检查str1是否比str2大 |
-n str1 | 检查str1的长度是否非0 |
-z str1 | 检查str1的长度是否为0 |
有一个问题需要注意,对于<和>,不能直接使用,因为它们在shell下有其它的语义,所以需要做转换:>要用\>,<要用\<。
3)文件(和目录)比较:
比较 | 描述 |
-d file | 检查file是否存在并是一个目录 |
-e file | 检查file是否存在 |
-f file | 检查file是否存在并是一个文件 |
-x file | 检查file是否存在并可执行 |
file1 -nt file2 | 检查file1是否比file2新 |
file1 -ot file2 | 检查file1是否比file2旧 |
另外,对于字符串的比较,还可以使用[[ expression ]]进行模式匹配,下面是一个例子:
这里[[ ]]中的是正则表达式,在此不表。
for语句
for var in list
do
commands
done
下面是一个例子:
while语句和until语句
while/until test commands
do
commands
done
while语句和unitl语句的语义刚刚相反。
前者是test返回0时执行子语句,而后者是test返回非0时执行子语句。
下面是一个while的例子:
下面是一个until的例子:
上述两个示例的结果一致。