shell中$*和$@的区别

本文介绍如何在Shell脚本中正确地将参数从一个脚本传递到另一个脚本,重点对比了$*与$@的区别及应用。通过示例演示了如何保持参数的完整性,尤其是在遇到带空格的参数时。

如果想用一个shell脚本把输入参数完整的传给另一个脚本,特别遇到以下这种情况的时候./a.sh 'test 1' 'test 2'。此时就需要使用$@,而不是$*来完成需求。具体运行一下以下脚本就清楚这两条命令之间的区别了。

b.sh

echo pn:$#
echo p: $*
echo p: $@

 a.sh

echo $#
echo './b.sh $*'
./b.sh $*
echo './b.sh $@'
./b.sh $@
echo './b.sh "$*"'
./b.sh "$*"
echo './b.sh "$@"'
./b.sh "$@"
 

运行./a.sh 'a b' c d

输出结果为

3
./b.sh $*
pn:4
p: a b c d
p: a b c d
./b.sh $@
pn:4
p: a b c d
p: a b c d
./b.sh "$*"
pn:1
p: a b c d
p: a b c d
./b.sh "$@"
pn:3
p: a b c d
p: a b c d

 

<think>我们正在讨论shell脚本中的特殊变量,特别是$*的含义。根据引用[1]引用[2]: 引用[1]提到:$* 以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个。 引用[2]中给出了一个例子,展示了$@$*区别。 具体来说: $* 表示所有位置参数被作为一个字符串(由$IFS的第一个字符分隔,默认是空格)组合起来。 例如,如果脚本有三个参数:arg1 arg2 arg3,那么$*相当于"arg1 arg2 arg3"(一个字符串)。 在引用[2]的示例中,通过三个循环展示了$@$*区别: 1. 使用"$@":每个参数都被视为独立的单词,因此循环会遍历每个参数。 2. 使用"$*":所有参数被合并成一个单词(字符串),因此循环只执行一次,整个字符串作为一个元素。 3. 使用$*(不加引号):这时会进行单词分割,每个参数分开,循环会遍历每个参数($@不加引号的行为类似,但有区别,因为$@加引号时仍能保持每个参数的独立性)。 因此,$*的主要特点: - 当用双引号括起来时("$*"),它把所有位置参数合并成一个单词,单词之间用$IFS的第一个字符(默认为空格)分隔。 - 当不用双引号时($*),它会把所有位置参数展开,然后进行单词分割(根据IFS),每个参数成为独立的单词(但注意,如果参数中包含空格,则会被拆分,所以通常建议使用"$@"来逐个获取参数)。 总结:$* 代表所有位置参数,但它的行为取决于是否被引号括起来。 引用[1]还提到:$@ 是传给脚本的所有参数的列表。而$*是以一个单字符串显示所有参数。 举例说明: 假设脚本test.sh内容如下: #!/bin/bash echo "Using \"\$*\":" for arg in "$*"; do echo "$arg" done echo "Using \$* (without quotes):" for arg in $*; do echo "$arg" done echo "Using \"\$@\":" for arg in "$@"; do echo "$arg" done 执行:./test.sh a b "c d" 输出: Using "$*": a b c d # 注意这里是一整行输出,因为"$*"把三个参数合并成一个字符串(a,b,"c d"被合并成一个字符串,中间用空格连接) Using $* (without quotes): a b c d # 这里因为没有引号,$*展开后进行了单词分割,所以"c d"被分成了两个单词 Using "$@": a b c d # 这里保留了第三个参数"c d"的完整性 所以,在需要逐个处理参数且保留参数内空格时,通常使用"$@"。 根据引用[3]没有直接关于$*的内容,但提供了其他$变量操作。 因此,$*的含义是:将所有的位置参数作为一个字符串(默认以空格分隔)返回。 相关问题: 1. Shell脚本中$*$@区别是什么? 2. 如何正确处理脚本中的位置参数? 3. 为什么在循环遍历参数时推荐使用"$@"? 4. 如何修改$*中使用的分隔符? 5. Shell脚本中如何获取位置参数的数量? </think>在 Shell 脚本中,`$*` 是一个特殊的预定义变量,用于表示**传递给脚本的所有位置参数的集合**。其核心特性用法如下: ### 1. **基本含义** `$*` 将所有位置参数(`$1`, `$2`, `$3`...)扩展为**单个字符串**: - 默认以空格分隔参数 - 等价于 `"$1 $2 $3 ..."` - 示例: ```bash # 脚本内容:echo $* ./script.sh arg1 "arg 2" arg3 → 输出:arg1 arg 2 arg3 ``` ### 2. **与 `$@` 的关键区别** | 特性 | `$*` | `$@` | |----------------|----------------------------------|-------------------------------------| | **扩展形式** | 所有参数合并为单字符串 | 每个参数保持独立 | | **引号处理** | `"$*"` = 单字符串(含所有参数) | `"$@"` = 保留参数的原始分词引号 | | **循环遍历** | 循环只执行 1 次 | 循环执行 N 次(每个参数一次) | 引用[2]的示例代码验证: ```bash n=1 for i in "$*"; do echo "$n : $i" # 输出:1 : arg1 arg2 arg3(单次循环) let n+=1 done n=1 for i in "$@"; do echo "$n : $i" # 输出: let n+=1 # 1 : arg1 done # 2 : arg2 # 3 : arg3 ``` ### 3. **使用场景** - **批量传递参数** 需将多个参数作为单个字符串处理时使用: ```bash grep "pattern" $* # 等价于 grep "pattern" $1 $2 $3 ... ``` - **兼容性场景** 某些旧命令要求参数为单字符串时有用(现代脚本更推荐用 `"$@"`)。 ### 4. **注意事项** - **参数包含空格时可能出错** ```bash ./script.sh "Hello World" → $* 输出 Hello World(正确) 但 for i in $* 会错误分词为 "Hello" "World" ``` - **优先使用 `"$@"`** 大多数场景下,保留参数原始结构的 `"$@"` 更安全(避免分词错误)[^2]。 ### 5. **与其他变量的关系** | 变量 | 含义 | 示例(`./script.sh a "b c" d`) | |------|-------------------------------|--------------------------------| | `$#` | 参数个数 | `3` | | `$0` | 脚本名称 | `script.sh` | | `$@` | 参数列表(保留分词) | `(a "b c" d)` | | `$*` | 参数合并为单字符串 | `a b c d` | --- ### 相关问题 1. Shell 脚本中如何处理带空格的文件路径参数? 2. `"$*"` `$*` 在双引号内使用时有何区别? 3. 为什么在循环遍历参数时推荐使用 `"$@"` 而非 `$*`? 4. 如何修改 `$*` 默认的分隔符(空格)? 5. `$*` 在函数内部全局脚本中的行为是否一致? [^1]: 引用[1] [^2]: 引用[2] [^3]: 引用[3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值