本节课将对 shell 编程进行系统的讲解。目标具备一定的 shell 脚本编程能力,为后续学习打下基础
shell 脚本的基础知识
shell 脚本的本质
- 编译型语言
- C 语言
- 解释型语言
- shell 脚本语言是解释型语言
- shell 脚本的本质:shell 命令的有序集合
shell 编程的基本过程,基本过程分为三步:
- 建立 shell 文件(.sh)
包含任意多行操作系统命令或shell命令的文本文件; - 赋予 shell 文件执行权限
用chmod
命令修改权限; - 执行 shell 文件
直接在命令行上调用 shell 程序。
实例
-
建立 shell 文件(可用任何建立文本文件的方法)
$ cat prog1.sh date
-
赋予执行权限:(初始文本文件无执行权限)
$ chmod 740 prog1.sh
-
执行该 shell 程序
$ prog1.sh prog1.sh: not found
shell 在标准搜索路径中找不到 prog1.sh
-
指定路径或修改环境变量
PATH
后执行 shell 程序$ ./prog1.sh 2009年 12月 16日 星期二 14:52:57 CST
shell 变量
位置变量
$0
与键入的命令行一样,包含脚本文件名$1,$2,……$9
分别包含第一个到第九个命令行参数$#
包含命令行参数的个数(不包含脚本的名字)$@
包含所有命令行参数:$1,$2,……$9
$?
包含前一个命令的退出状态(成功:0
),得到函数的返回值$*
包含所有命令行参数:$1,$2,……$9
$$
包含正在执行进程的 ID 号
shell 脚本-说明性、功能性、测试语句
shell 程序由零或多条 shell 语句构成。 shell 语句包括三类:说明性语句、功能性语句和结构性语句。
- 说明性语句:以
#
开始到该行结束,不被解释执行 - 功能性语句:任意的 shell 命令、用户程序或其它 shell 程序
- 结构性语句:条件测试语句、多路分支语句、循环语句、循环控制语句等
说明性语句(注释行)
注释行可以出现在程序中的任何位置,既可以单独占用一行, 也可以接在执行语句的后面。以 #
开始到所在行的行尾部分,都不被解释执行。例如:
#! /bin/sh
# ------> 告诉OS用哪种类型的shell来解释执行该程序
# 本程序说明
#
command_1
command_2 # command_2的语句说明
……
# 下面程序段的说明
command_m
……
command_n # command_n语句的说明
……
常用功能性语句(命令)
read
命令
read
从标准输入读入一行,并赋值给后面的变量,其语法为:
read var
把读入的数据全部赋给var
read var1 var2 var3
把读入行中的第一个单词(word)赋给var1
, 第二个单词赋给var2
,…… 把其余所有的词赋给最后一个变量。
如果执行 read
语句时标准输入无数据,则程序在此停留等侯,直到数据的到来或被终止运行。
应用实例
-
# example1 for read echo -e "Input your name: \c" read username echo "Your name is $username"
-
#example2 for read echo -e "Input date with format yyyy mm dd: \c" read year month day echo "Today is $year/$month/$day, right?" echo "Press enter to confirm and continue\c" read answer echo "I know the date, bye!"
-e
使\c
生效\c
不换行
expr
命令
算术运算命令 expr
主要用于进行简单的整数运算,包括加 +
、减 -
、乘 *
、整除 /
和求模 %
等操作。例如:
$ expr 12 + 5 \* 3 # 反斜线去掉 * 号的元字符含义
27
$ expr 3 - 8 / 2
-1
$ num=9
$ sum=`expr $num \* 6` # 反撇号引用命令的运行结果
$ echo $sum
54
shift
命令
位置参数可以用 shift
命令左移。比如 shift 3
表示原来的 $4
现在变成 $1
,原来的 $5
现在变成 $2
等等,原来的 $1
、$2
、$3
丢弃,$0
不移动。不带参数的 shift
命令相当于 shift 1
。
非常有用的 Unix 命令:shift
。我们知道,对于位置变量或命令行参数,其个数必须是确定的,或者当 Shell 程序不知道其个数时,可以把所有参数一起赋值给变量 $*
。若用户要求 Shell 在不知道位置变量个数的情况下,还能逐个的把参数一一处理,也就是在 $1
后为 $2
,在 $2
后面为 $3
等。在 shift
命令执行前变量 $1
的值在 shift
命令执行后就不可用了。
示例如下:
#测试 shift 命令(x_shift.sh)
until [ $# -eq 0 ]
do
echo "第一个参数为: $1 参数个数为: $#"
shift
done
执行以上程序 x_