### shell变量

- 数组

  ```
  # shell只支持一维数组
  array_name = (val0 ... valn)	# 数组的定义方式一
  array_name[0] = val0			# 数组的定义方式二
  ${array_name[index]}			# 读取数组的元素
  ${array_name[*]}				# 读取数组中的所有元素方式一
  ${array_name[@]}				# 读取数组中的所有元素方式二
  ${#array_name[*]}				# 获取数组长度方式一
  ${#array_name[@]}				# 获取数组长度方式二
  ```

### 算术运算

算术运算符

| 算术运算符                 | **含义** | 示例          |
| -------------------------- | -------- | ------------- |
| +、 -                      | 加减     | echo $((1+1)) |
| *、 /、 %                  | 乘除取余 |               |
| **                         | 幂       |               |
| ++、 --                    | 自增自减 |               |
| !、 &&、 \|\|              | 逻辑     |               |
| <、 <=、 >、 >=            | 比较     |               |
| ==、 != =                  | 比较     |               |
| <<、 >>                    | 移位     |               |
| ~、 \|、 &、 ^             | 位运算   | echo $((0&1)) |
| =、 +=、 -=、 *=、 /=、 %= | 赋值运算 |               |

运算命令

| 运算命令   | 说明                                 |
| ---------- | ------------------------------------ |
| (())       | 整数运算                             |
| let        | 数学运算                             |
| $[]        | 整数运算                             |
| expr       | 整数运算，或处理字符串               |
| bc         | 整数、小数运算                       |
| declare -i | 将变量定义为整数，仅支持加减乘除取余 |



### 函数

```bash
function help(){
  echo "help"
}
```



# --------------------

#### 基本格式

  * 第1行总是以`#!/bin/sh`开始，通知shell使用何种解释器。
  * 以`#`开头的行是注释，建议在第二行注释中写入脚本名。
  * 脚本按从上到下的顺序执行。

#### 保留字和元字符

```
do, done, for, while
if, then, else
```

```shell
..	# 上级目录
.	# 当前目录
*	# 任意多个字符
?	# 任意一个字符
~	# 用户目录
$	# 变量参数
#	# 注释
|	# 管道
&	# 后台执行
&&	# 左边的命令返回真后，右边的命令才能执行
||	# 左边的命令执行错误，则执行右边的命令
()	# 在当前shell执行括号内的一组命令
{}	# 在子shell执行括号内的一组命令
[...]	# 匹配括号内的任意一个字符
[!...]	# 不包含括号内的所有字符
>	# 标准输出重定向
cmd 2> file	# 把标准错误重定向到file
2>&1	# 把标准错误和标准输出都作为标准输出，然后重定向。其实现原理是把标准输出的文件描述符复制给标准错误。
>>	# 标准输出追加
cmd 2>> file	# 把标准错误追加到file
	# cmd >> file 2>&1，把标准输出和标准错误都追加到file里，等同于cmd &>> file
<	# 输入重定向
	# cat < abc.txt 意思就是把abc.txt作为cat命令的输入
命令 << 分界符	# 从标准输入设备读入，直到分界符才停止
	# cat << 0	意思是从键盘(标准输入)输入字符到cat命令，直到0才停止
cmd < file1 > file2	# file1的内容作为cmd命令的输入，cmd命令的输出放在file2里。

# shell可识别4种引字符号：
'	# 单引号。两个单引号之间的特殊字符均被识别为普通字符。
"	# 双引号。两个单引号之间的特殊字符大部分被识别为普通字符，但不包含单引号、反斜杠、$。
\	# 反斜杠。转义或在行尾表示续行。
`	# 反引号。两个反引号之间的命令被替换为这个命令的输出。$()也有此作用。反引号不能嵌套，而$()可以嵌套。
```

#### shell变量

##### 整型变量

- 变量默认是字符串，要让它是整型需要这么写`var=$((3))`。

##### 本地变量

- 仅对当前进程有效

##### 环境变量

- 对所有进程有效

- export导出环境变量
- env显示环境变量
- unset清除环境变量

##### 特定变量

```
!!		# 上条命令
!#		# 上条命令的名称
!^		# 上条命令的第一个参数
!$		# 上条命令的最后一个参数
!:n		# 上条命令的第n个参数
!:n-m	# 上条命令从n到m条参数
!:n*	# 上条命令从n开始到最后一条参数
!*		# 上条命令的所有参数

$0		# 当前脚本的文件名
$num	# 表示传递给脚本的第num个参数，num从1开始
$#		# 传递给脚本的参数个数
$*		# 表示所有参数。即"$1" "$2" ... "$n"。"$*"表示"$1 $2 ... $n"。
$@		# 表示所有参数。不论是否使用引号，都表示"$1" "$2" ... "$n"。
$?		# 上条命令的返回值，成功为0，不成功为非0
$$		# 当前shell的pid
$!		# 后台运行的最后一个进程的pid
$-		# shell使用的当前选项
$_		# 上条命令的最后一个参数
```

##### 在变量中切割字符串

```
# 假设var=http://www.abc.com/test.htm
${parameter:-word}	# 如果parameter有值则取其值，否则结果为word
${parameter:=word}	# 如果parameter有值则取其值，否则结果为word
${parameter:?word}	# 如果parameter有值则取其值，否则结果为word
${parameter:+word}	# 无论parameter是否有值，结果为总是word
${#parameter}		# 获取字符串的长度，例如${#var}的结果为27
${parameter%word} 	# 最小限度从后面截取word
${parameter%%word} 	# 最大限度从后面截取word
${parameter#word} 	# 最小限度从前面截取word，例如${var#*/}的结果为/www.abc.com/test.htm
${parameter##word} 	# 最大限度从前面截取word，例如${var##*/}的结果为test.htm

${parameter:start}	# 从start开始获取字符串，如${var:7}的结果为www.abc.com/test.htm
${parameter:start:len}	# 从start开始截取len个字符，如${var:7:3}的结果为www
${parameter:start-len}	# 先取最右的len个字符，然后再从所得的字符串的start位开始截取，如${var:3-5}和${var:2-4}的结果都是tm
${parameter:start-len1:len2}	# 先取最右的len1个字符，然后再从所得字符串的start位开始截取长度为len2的字符。如${var:3-5:1}的结果是t
```

