# Shell中$#、$0、set等的含义



### **Shell脚本变量$#,$\*等的含义**

```shell
$#      # 表示执行脚本传入参数的个数
$*      # 表示执行脚本传入参数的列表（不包括$0）
$$      # 表示进程的id
$@      # 表示执行脚本传入参数的所有个数（不包括$0）
$0      # 表示执行的脚本名称
$1      # 表示第一个参数
$?      # 表示脚本执行的状态，0表示正常，其他表示错误
```

**例子**

```shell
#!/usr/bin/env bash

printf "the process id is %s\n" "$$"        # 进程ID
printf "the return value is %s\n" "$?"      # 脚本返回值
printf "the all argus is %s\n" "$*"         # 传入的参数列表
printf "the argus is %s\n" "$@"             # 循环输出传入的参数
printf "the number of argus is %s\n" "$#"    # 传入参数的数量
printf "the first argus0 is %s\n" "$0"      # 当前执行的脚本名字
printf "the argus 1 is %s\n" "$1"           # 输出传入第一个参数
printf "the argus 2 is %s\n" "$2"           # 输出传入第二个参数
```

**结果**

```shell
# ./shell.sh 123 456
the process id is 108329
the return value is 0
the all argus is 123 456
the argus is 123
the argus is 456
the number of argus is 2
the first argus0 is ./a.sh
the argus 1 is 123
the argus 2 is 456
```

### **$\*和$@的差异**

> 在shell中，$@和$\*都表示命令行所有的参数（不包含$0）,但是$\*将命令行所有的参数看成一个整体，而$@则区分各个参数

```shell
#!/usr/bin/env bash

echo "the all para:"
for i in "$@" ; do echo $i  ; done

echo "the all para:"
for i in "$*" ; do echo $i; done

#### 执行： ./shell.sh 1 2 3  结果
the all para:
1
2
3
the all para:
1 2 3
```





### 显示所有环境变量

```bash
set
```

### 脚本常用set命令

* 减号-是开启了某种模式，加号 +则是关闭对应的模式

```bash
# 遇到错误后脚本会直接退出，不会继续往下执行
set -e
set +e


# 执行脚本的时候，如果遇到不存在的变量，Bash 默认忽略它，set -u可以在需要的变量不存在的时候直接报错退出
set -u
set +u


# 对于复杂的脚本可以局部开启调试
set -x
set +x


set -o pipefail  # 对上面的 set -e的补充, 因为set -e对于管道符是无效的
set +o pipefail
```
