# 第七章 shell程序设计
## 7.1 shell概述
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。
业界所说的 shell 通常都是指 shell 脚本,但读者朋友要知道,shell 和 shell script 是两个不同的概念。
由于习惯的原因,简洁起见,本文出现的 "shell编程" 都是指 shell 脚本编程,不是指开发 shell 自身。
------
### 7.1.1 shell的特点
1. 把已有命令进行适当组合,构成新的命令,而且组合方式简单
2. 提供文件扩展字符
3. 可以直接使用shell内置命令
4. 灵活使用数据流、提供通配符等
5. 支持顺序、条件、循环控制
6. 提供后台(&)执行命令
7. 提供可配置环境
8. 提供高级命令语言
**类型**
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
- ....
查看使用类型方法
``
## 7.1.2 shell脚本的建立和执行
### 建立脚本
**一般格式**
```
vi/vim {file.sh/file}
```
### **执行脚本**
**1.bash**
**一般格式**
```
bash {file} {参数}
```
**例**
`bash ex2`
**2.shell**
**一般格式**
```
./{文件名}
```
**修改权限**
**一般格式**
```
chmod {权限} {文件名}
```
**例**
```
chmod a+x ex2
PATH=$PATH: .
```
## 7.2 shell变量和算术运算符
### 7.2.1 简单shell变量
1.**变量定义和赋值**
**一般形式**
```
变量名=字符串
```
**例**
保存路径
```
myfile = /home/menggcc
```
2.**应用变量名**
**例**
```
echo $ myfile
ls $ myfile
cat $ myfile
```
### 7.2.2 数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。
**定义数组**
```
数组名=(值1 值2 ... 值n)
```
**例**
```
array_name=(value0 value1 value2 value3)
```
或
```
array_name=(
value0
value1
value2
value3
)
```
或
```
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
```
**读取数组**
```
${数组名[下标]}
```
**例**
```
valuen=${array_name[n]}
@/* 获取所有元素
echo ${array_name[@]}
echo ${array_name[*]}
```
### 7.2.3 位置参数
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:**$n**。**n** 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
**例**
```
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
```
**执行**
```
$ chmod +x test.sh
$ ./test.sh 1 2 3
Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
```
**处理参数**
| 参数处理 | 说明 |
| :------- | :----------------------------------------------------------- |
| $# | 传递到脚本的参数个数 |
| $* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
| $$ | 脚本运行的当前进程ID号 |
| $! | 后台运行的最后一个进程的ID号 |
| $@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 |
| $- | 显示Shell使用的当前选项,与[set命令](#)功能相同。 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
## 7.3 输入/输出及重定向命令
## 7.4 shell特殊字符和命令语法
### 7.4.1 引号
#### 双引号
由双引号括起来的字符 (除 $ , ` , \ 外)
#### 单引号
由单引号括起来的所有字符都作为普通字符出现
#### 倒引号
字符串将解释为shell命令来执行
### 7.4.2 注释、管道和后台命令
#### 注释
以`#!`开头后面跟注释内容
`#!{路径名}`
#### 管道线
管道线是由竖杠(|)隔开的若干个命令组成的序列。
**例**
```bash
$ ls -l $HOME|wc -l
```
**说明:**
ls -l $HOME以长列表的格式输出用户主目标的内容,传给命令wc -l,统计出他有多少行,并在屏幕上显示,例如:显示99,就表示用户主目录有99个文件
#### 后台命令
在命令的最后输入`&`
**例**
```bash
$ gcc m1.c m2.c -o prog&
```
### 7.4.3 命令执行操作符
#### 顺序执行
每条命令或管到你可单独占一行,按其出现顺序依次执行。也可将这些命令在一行中输出,此时命令之间应以封号(;)隔开
**例**
```bash
$ pwd; who|wc -l; cd /home/bin
```
