Bash的$@和$*

news/2025/1/22 17:05:47/文章来源:https://www.cnblogs.com/smartljy/p/18686443

深入理解 $@ 与 Bash 参数处理

在 Bash 脚本编写中,$@$* 都用于处理 脚本参数(Positional Parameters),但它们的行为有所不同,理解它们的区别至关重要。本文将深入剖析它们的用法、适用场景,并对比 "$@""$*" 在不同场景下的表现。


1. $@$* 的基本概念

在 Bash 中:

  • $@ 代表所有参数,并保持参数的分割性
  • $* 也代表所有参数,但会将它们合并成一个字符串

假设我们编写了一个 Bash 脚本 test.sh,其内容如下:

#!/bin/bashecho "Using \$*: $*"
echo "Using \$@: $@"echo "Iterating over \$*:"
for arg in "$*"; doecho "Arg: $arg"
doneecho "Iterating over \$@:"
for arg in "$@"; doecho "Arg: $arg"
done

然后,我们执行:

bash test.sh "hello world" "foo bar" baz

让我们看看输出结果:

Using $*: hello world foo bar baz
Using $@: hello world foo bar bazIterating over $*:
Arg: hello world foo bar baz  # 🚨 变成了一个整体!Iterating over $@:
Arg: hello world
Arg: foo bar
Arg: baz  # ✅ 正确地分割了参数

分析

  1. "$*" 将所有参数合并成一个字符串,结果 "hello world foo bar baz" 变成了一个整体
  2. "$@" 保持参数的分割性,所以 for arg in "$@" 仍然正确地遍历了 "hello world""foo bar"baz

✅ 结论:"$@" 更安全,推荐使用!


2. "$@""${array[@]}"

Bash 也支持数组操作,数组变量可以使用 "$@" 类似的方式展开。

示例

#!/bin/bash
array=("hello world" "foo bar" "baz")echo "Using \"\${array[*]}\": ${array[*]}"
echo "Using \"\${array[@]}\": ${array[@]}"echo "Iterating with \"\${array[*]}\":"
for item in "${array[*]}"; doecho "Item: $item"
doneecho "Iterating with \"\${array[@]}\":"
for item in "${array[@]}"; doecho "Item: $item"
done

执行

Using "${array[*]}": hello world foo bar baz
Using "${array[@]}": hello world foo bar bazIterating with "${array[*]}":
Item: hello world foo bar baz  # 🚨 变成了一个整体!Iterating with "${array[@]}":
Item: hello world
Item: foo bar
Item: baz  # ✅ 正确保持分割

总结

语法 作用 适用场景
"$*" 把所有参数合并成一个字符串 不推荐,可能导致错误
"$@" 逐个传递参数(不会丢失空格) 推荐,适用于函数参数传递
"${array[*]}" 把整个数组合并成一个字符串 不推荐,容易丢失原始分割
"${array[@]}" 保持数组元素完整 推荐,适用于数组遍历

3. "$@" 在函数参数传递中的作用

在 Bash 函数中,"$@" 是最安全的方式来传递参数,否则可能会导致参数解析错误。例如:

错误示例(使用 "$*"

my_function() {echo "Arguments:"for arg in "$*"; doecho "$arg"done
}my_function "hello world" "foo bar"

输出

Arguments:
hello world foo bar  # 🚨 参数被错误合并!

"$*" 导致 "hello world""foo bar" 变成一个整体,这是错误的。


正确示例(使用 "$@"

my_function() {echo "Arguments:"for arg in "$@"; doecho "$arg"done
}my_function "hello world" "foo bar"

输出

Arguments:
hello world
foo bar  # ✅ 参数保持完整!

✅ 结论:在函数参数传递中,永远使用 "$@"


4. "$@" 在 Git Hook 及 Shell Wrappers 中的应用

在 Git Hook 或 Shell Wrappers(封装 Git 命令的脚本)中,我们通常希望 将所有用户传入的参数原样传递给 git 命令。如果不小心使用了 "$*",可能会导致命令执行失败。例如:

错误示例(使用 "$*"

git() {command git "$*"
}git commit -m "Fix bug"

这会被解析为:

git "commit -m Fix bug"  # 🚨 错误!

Git 可能会报错,因为 commit -m "Fix bug" 变成了一个整体字符串


正确示例(使用 "$@"

git() {command git "$@"
}git commit -m "Fix bug"

这会正确解析为:

git commit -m "Fix bug"  # ✅ 正确!

结论在 Shell Wrappers 中,始终使用 "$@" 以确保参数传递正确!


5. 结论

语法 作用 适用场景 推荐指数
"$*" 把所有参数合并成一个字符串 🚨 不推荐,容易导致参数解析错误
"$@" 逐个传递参数,保持原始分割 推荐,适用于函数参数传递 ⭐⭐⭐⭐⭐
"${array[*]}" 把整个数组合并成一个字符串 🚨 不推荐,容易导致数据丢失
"${array[@]}" 逐个传递数组元素,保持原始分割 推荐,适用于数组遍历 ⭐⭐⭐⭐⭐

🚀 最佳实践

  • 函数参数传递Shell Wrappers 中,始终使用 "$@"
  • 数组展开 时,使用 "${array[@]}" 以保持数据完整。
  • 避免 使用 "$*""${array[*]}",除非你明确希望合并所有参数或数组元素为单个字符串。

📌 牢记这点,你的 Bash 脚本会更健壮、更安全!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873314.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GDB - 查看崩溃程序maps映射表

可执行程序如何通过gdb查看映射信息? 在终端中打开gdb调试器:gdb 可执行文件名。 进入gdb调试器后,使用命令info proc mapping查看可执行程序的映射信息。 这个命令将会输出可执行程序的内存映射信息,包括可执行文件的代码段、数据段、堆和栈等信息,以及共享库的地址空间等…

Anthropic 计划为 Claude 发布「双向」语音模式;商汤「日日新」实时音视频对话服务开放商用丨 RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内容仅代表编辑…

记录---当window.open被ios安全机制拦截,我掏出3种方案,终于跳转成功!

🧑‍💻 写在开头 点赞 + 收藏 === 学会🤣🤣🤣一、前言 今天在开发H5的时候,遇到了一个bug,就是在ios环境,在某些情况下执行window.open不生效,所以正好趁此机会研究了一下window.open。 二、window.open介绍 从open方法的调用方式可以看出,open方法是定义在Wind…

C. Gawr Gura

小鲨鱼cos本来有三张但是被审核夹了,只发两张试试..?

马拉车 Manacher

讲解马拉车算法,模板例题与代码更新日志 2025/01/22:开工。思路 马拉车算法用于解决回文子串问题,思路类似于Z函数。 首先我们考虑使所有回文串都是奇数串,具体的,我们在两两字符之间插入相同的特殊字符,比如: \[\texttt{abcba}\rightarrow\texttt{\#a\#b\#c\#b\#a\#} \…

折腾笔记[10]-使用rust进行ORB角点检测

打包ORB算法到bye_orb_rs库,使用rust进行ORB角点检测. Package the ORB algorithm into the bye_orb_rs library, and use Rust for ORB corner detection.摘要 打包ORB算法到bye_orb_rs库,使用rust进行ORB角点检测. Package the ORB algorithm into the bye_orb_rs library, a…

DBSyncer开源数据同步中间件

一、简介 DBSyncer(英[dbsɪŋkɜː(r)],美[dbsɪŋkɜː(r) 简称dbs)是一款开源的数据同步中间件,提供MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步场景。支持上传插件自定义同步转换业务,提供监控全量和增量数据统计图、应用性能预…

幻想 实在 自我

小 C 和 小 Y 的故事还未停止 …… 或许不会停止弥晨时间仓促,如有错误欢迎指出,欢迎在评论区讨论,如对您有帮助还请点个推荐、关注支持一下

AT+CSQ 和 AT+QENG查询的 RSSI不一致

1. 查询结果如下:2. CSQ查询的RSSI 接收信号强度指示时是31,对应但是 AT+QENG查询的是-128

记录printf的一个小问题

因为打算使用sprintf来格式化字符串,然后显示,遇到了一个符号类型的问题 printf("%d",now_adc);这一句,如果now_adc是uchar类型,输出字符会显示异常,后来了解到,如果要直接打印uchar只能用%x或者%s 所以如果不想改变量大小可以在前面加括号强转如printf("…

工业人工智能白皮书2025年:边缘AI驱动,助力新质生产力报告汇总PDF洞察(附原数据表)

原文链接:https://tecdat.cn/?p=38940 在当前科技变革的浪潮中,工业领域正经历着深刻转型。人工智能与工业互联网等前沿技术的迅猛发展,为工业的升级演进带来了前所未有的机遇与挑战。 本报告汇总洞察聚焦工业领域的变革趋势,深入剖析其核心驱动力与发展脉络。通过对工业 …

【视频】R语言支持向量分类器SVM原理及房价数据预测应用及回归、LASSO、决策树、随机森林、GBM、神经网络对比可视化

全文链接: https://tecdat.cn/?p=38830 原文出处:拓端数据部落公众号 分析师:Yuqi Liu 在大数据时代,精准的数据分类与预测对各领域的发展至关重要。超平面作为高维空间中的关键概念,可将线性空间一分为二,为数据分类奠定了理论基石。基于此发展而来的最大边缘分类器,…