这篇介绍shell的语法,包括shell中的变量,条件判断,控制结构和函数。上篇介绍了什么是shell,管道和重定向,作为程序设计语言的shell,下一篇是shell的命令与命令的执行,此外,这篇的所有命令都在变量条件控制结构函数下载。
Shell的语法
2.6.1 变量
在 shell里,使用变量之前不需要事先为它们做出声明,只是通过使用它们来创建它们。在 默认情况下,所有变量都被当做字符串并以字符串来存储,即使它们被赋值为数值时也是如此。在shell中,可以 通过在变量名前加一个$符号来访问它的内容。想要获取变量内容,必须在它前面加上一个$字符。当为变量赋值时,只需要使用变量,该变量会根据需要自动创建。一种检查变量内容的简单方式是在变量名前加上一个$符号,再用echo命令将它的内容输出到终端上。例如:
$ a=bye
$ echo $a
bye
$ a="hello world"
$ echo $a
hello world
$ a=1+1
$ echo
1+1
1.使用引号
如果 字符串里包含空格,必须用引用把它们括起来,此外,等号两边不能有空格。可以使用read命令将用户的输入赋值给一个变量。通常情况下,在用户按下回车键时,read命令结束。当从终端上读取一个变量名时,一般不需要使用引号。
一般情况下,脚本文件中的参数以空白符分隔(空格,制表符,换行符),就必须给参数加上引号。
如果把一个 $变量表达式放在双引号中,程序执行到这一行时就会把变量替换为它的值;如果把它放在单引号中,就不会替换。还可以通过在$前面加上一个\字符以取消它的特殊含义。
2.环境变量
当一个shell脚本程序开始执行时,一些变量会根据环境设置中的值进行初始化。这些变量通常用大写字母做名字,以便把它们和用户在脚本程序里定义的变量区分开来,后者按照惯例都用小写字母做名字。环境变量 说明
$HOME 当前用户的家目录
$PATH 以冒号分隔的用来搜索命令的目录列表
$PS1 命令提示符
$PS2 二级提示符
$IFS 输入域分隔符
$0 shell脚本的名字
$# 传递给脚本的参数个数
$$ shell脚本的进程号,脚本程序通常会用它来生成唯一的临时文件,如/tmp/tmpefile_$ $
可以通过执行env <command>命令来查看程序在不同环境下是如何工作。
3.参数变量
如果 脚本程序在调用时带有参数,一些额外的变量就会被创建。即使没有传递任何参数,环境变量$#也依然存在,只不过它的值是0.参数变量 说明
$1,$2... 脚本程序的参数
$* 在一个变量中列出所有的参数,各个参数之间用环境变量IFS中的第一个分隔符分开
$@ 即使IFS为空,参数也不会挤在一起
双引号里面的$@把各个参数扩展为彼此分开的域,而不受IFS值的影响。一般来说,如果你想访问脚本程序的参数,使用$@是明智的选择。
#!/bin/sh
i="hello"
echo $i
echo "The program $0 is now running"
echo "The second parameter was $2"
echo "The first parameter was $1"
echo "The parameter list was $*"
echo "THe user's home directory is $HOME"
echo "Please enter a new greeting"
read i
echo $i
echo "The script is now complete"
exit 0
其中$0是shell脚本的名字,$1,$2是脚本程序的参数,$*在一个变量中列出所有的参数。
2.6.2 条件
所有程序设计语言的基础都是对条件的进行测试判断,并根据不同测试结果采取不同行动。一个 shell脚本能够对任何可以从命令行上调用的命令的退出码进行测试,其中也包括自己编写的脚本程序。这也就是要在所有自己编写的 脚本程序的结尾包括一条返回值的命令的重要原因。
test或[命令
大多数脚本程序都会广泛使用shell的布尔判断命令[或test
注意必须在 [符号和被检查的条件之间留出空格。如果把then和if放在同一行上,则需要使用一个分号把test语句和then分隔开。
test命令可以使用的条件类型可以分为3类:字符串比较,算术比较和与文件有关的条件测试。
字符串比较 结果
string1 = string2 如果两个字符串相同,则结果为真
string1 != string2 如果两个字符串不同,则结果为真
-n string 如果字符串不为空,则结果为真
-z string 如果字符串为null,则结构为真
算术比较 结果
expres1 -ep expres2 如果两个表达式相等,则结果为真
expres1 -ne expres2 如果两个表达式不等,则结果为真
expres1 -gt expres2 如果expres1大于expres2,则结果为真
expres1 -ge expres2 如果expres1大于等于expres2,则结果为真
expres1 -lt expres2 如果expres1小于
expres1 -le expres2 如果expres1小于等于
! expres 如果expres为假,则结果为真
文件条件测试 结果
-d file 如果文件是一个目录,则结果为真
-e file 如果文件存在,则结果为真(通常使用-f)
-f file 如果文件是一个普通文件,则结果为真
-g file 如果文件的set-group-id位被设置,则结果为真
-r file 如果文件可读,则结果为真
-s file 如果文件的大小不为0,则结果为真
-u file 如果文件的set-user-id位被设置,则结果为真
-w file 如果文件可写,则结果为真
-x file 如果文件可执行,则结果为真
2.6.3 控制结构
shell有一组控制结构,它们与其他程序设计语言中的控制结构类似。1.if语句
if conditonthen
statement
else
statement
fi
2.elif语句
3.判断条件时,注意给变量加上引号,这样一个空变量提供的就是合法测试了。
4.for语句
for variable in valuesdo
statement
done
5.while语句
因为在默认情况下,所有的shell变量值都被认为是字符串,所以for循环特别适合对于一系列字符串进行循环处理,但如果事先并不知道循环要执行的次数,那么使用while。while condition
do
statement
done
6.until语句
until conditiondo
statement
done
7.case语句
case variable inpattern [ | pattern] ...) statement;;
pattern [ | pattern] ...) statement;;
esac
8.命令列表
有时需要将多条命令连接成一个序列。AND列表
AND列表结构: 只有在前面所有的命令都执行成功的情况下才执行后一条命令。
statement1 && statement2 && statement3 && ...
从左向右执行每一条命令,&&的作用是检查前一条命令的返回值是否为true。
OR列表
OR列表结构允许我们 持续执行一系列命令直到有一条命令成功为止,其后的命令将不再被执行。
statement1 || statement2 || statement3 || ...
从左开始执行每条语句,如果一条命令返回的是false,它右边的下一条命令才能被执行。
9.语句块
如果想在某些允许使用单个语句的地方使用多条语句,可以把它们括在花括号{}中来构造一个语句块。
2.6.4 函数
要定义一个shell函数,只需要写出它的名字,然后是一对空括号,再把函数中的语句放在一对花括号中,如下所示:function_name(){
statement
}