# shell - 参数传递

我们可以在执行 Shell 脚本时，向脚本传递参数。在脚本内可以通过$n或${n}来获取第n个参数（当n>=10时，必须加花括号）。比如$1表示第一个参数，${10}表示第10个参数，其中$0表示脚本的名字。

示例：

```
#!/bin/bash

echo $0
echo $1
echo ${10}
echo ${11}
```

执行命令与结果（第一行为执行命令）：

```
# ./a.sh a b c d e f g h i j k 
./a.sh
a
j
k
```

另外，需要注意变量的多重解析（使用`eval`），比如如下代码

```
#!/bin/bash

name=""
age=""

for (( i=1; i<=$#; i++ )); do
    eval opt='$'{${i}}
    case ${opt} in
        --name)
            let "i++"
            eval name='$'{${i}}
            ;;
        --age)
            let "i++"
            eval age='$'{${i}}
            ;;
        *)
            echo "Error : invalid opt ${opt}"
            exit 1
    esac

echo "Name is : ${name}"
echo "Age is : ${age}"
```

我们运行脚本，可以看到如下输出

```
./a.sh --name peng --age 18
Name is : peng
Age is : 18
```

另外，还有几个特殊字符用来处理参数

| 参数符号 | 说明                                                                                    |
| ---- | ------------------------------------------------------------------------------------- |
| `$#` | 传递到脚本的参数个数                                                                            |
| `$*` | 以一个单字符串显示所有向脚本传递的参数。如`"$*"`用双引号括起来的情况、以`"$1 $2 … $n"`的形式输出所有参数                        |
| `$@` | 与`$*`相同，但是使用时加引号，并在引号中返回每个参数。如`"$@"`用引号括起来的情况、以`"$1" "$2" … "$n"` 的形式输出所有参数。差异具体见本节附录 |
| `$$` | 脚本运行的当前进程ID号                                                                          |
| `$!` | 后台运行的最后一个进程的ID号                                                                       |
| `$-` | 显示Shell使用的当前选项，与set命令功能相同                                                             |
| `$?` | 显示最后命令的退出状态。0表示没有错误，其他任何值表明有错误                                                        |

## 附录： `$*` vs `$@`

1、`$*`有双引号和没有双引号都是一样的效果 2、`$@`没有加双引号时，和`$*`是一样的效果，加了双引号效果不一样

* `$*`

`$*`与`"$*"`是把传递进来的所有参数作为一个字符串。比如我们传递三个参数"ab"、"cd"、"ef"，那么`$*`和`"$*"`会把它们作为一个参数`'ab cd ef'`

示例：

```
#!/bin/bash

echo 'usage of $*'
for arg in $*; do
    echo $arg
done

echo 'usage of "$*"'
for arg in $@; do
    echo $arg
done
```

执行命令与结果如下：

* `$@`

有双引号时，`$@`会把参数利用IFS（默认为空格）进行切割，然后拆分成多个参数。

示例：


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://pshizhsysu.gitbook.io/shell/shell-can-shu-chuan-di.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
