Shell脚本中的位置参数( $0、$n、${10} ) 、特殊参数( $#、${!#}、$*、$@ )、shift命令和read命令详解

本文详细介绍了Shell脚本中位置参数($0, $n, ${10})、特殊参数($#, ${!#}, $*, $@)、shift命令的使用,并通过实例解析了read命令如何实现交互式输入及限制输入字符数。" 5322317,790773,IBM RFT自动化测试教程:适用范围解析,"['测试', 'IBM', '自动化测试工具', 'Rational Functional Tester', 'Eclipse']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、命令行参数
向shell脚本传递数据的最基本方法是使用命令行参数。命令行参数允许在运行脚本时向命令行添加数据。
bash shell中有一种特殊的变量叫——位置参数,位置参数变量是标准的数字:$0是程序名,$1是第一个参数,$2是第二个参数,依次类推,直到第九个参数$9。

[root@relay3.mobvista.com:101.251.254.6 shell]#cat test.sh
#!/bin/bash
echo "The zero parameter is set to : $0"
[root@relay3.mobvista.com:101.251.254.6 shell]#sh test.sh
The zero parameter is set to : test.sh

但是这里存在一些问题,如果使用另一个命令来运行shell脚本,命令会和脚本名混在
一起,出现在$0参数中。或者说,当我们以绝对路径调用时,也会返回绝对路径。

[root@relay3.mobvista.com:101.251.254.6 shell]#./test.sh
The zero parameter is set to : ./test.sh

[root@relay3.mobvista.com:101.251.254.6 shell]#sh /root/shell/test.sh
The zero parameter is set to : /root/shell/test.sh

要编写一个根据脚本名来执行不同功能的脚本时,我们需要显示单纯的脚本名,而basename命令可以做到,它会返回不包含路径的脚本名。

[root@relay3.mobvista.com:101.251.254.6 shell]#cat test.sh
#!/bin/bash
name=$(basename $0)
echo "The zero parameter is set to : $name"
[root@relay3.mobvista.com:101.251.254.6 shell]#sh test.sh
The zero parameter is set to : test.sh
[root@relay3.mobvista.com:101.251.254.6 shell]#sh /root/shell/test.sh
The zero parameter is set to : test.sh

当脚本需要的命令行参数不止9个时,必须在变量数字周围加上花括号,比如${10}表示第十个参数。

[root@relay3.mobvista.com:101.251.254.6 shell]#cat test.sh
#!/bin/bash
total=$[ ${10} * ${11} ]
echo "The tenth is ${10}"
echo "The eleventh is ${11}"
echo "Th
<think>我们正在讨论Shell脚本参数引用加引号的作用。具体来说,当我们使用位置参数(如$1, $2等)时,加上双引号("$1")不用引号($1)有什么区别? 参考引用: [^2] 提到了特殊变量$1-$9代表参数$@$*代表所有参数。 [^4] 详细说明了$@$*在加双引号不加引号时的区别。 主要问题:在Shell脚本中,给参数扩展(如$1, $2等)加上引号的作用是什么? 回答思路: 1. 不加引号时,参数扩展会进行单词拆分(word splitting)通配符扩展(globbing)。 2. 加双引号可以防止单词拆分通配符扩展,保留参数的原样。 具体解释: - 单词拆分:Shell会将变量的值按照内部字段分隔符(IFS,默认为空格、制表符、换行符)拆分成多个单词,然后作为多个参数传递。 - 通配符扩展:如果变量的值包含通配符(如*或?),Shell会尝试将其匹配的文件名进行扩展。 因此,当参数包含空格或特殊字符时,加引号可以确保参数被当作一个整体处理。 举例说明: 假设我们有一个脚本test.sh: ```bash #!/bin/bash echo "参数个数: $#" echo "第一个参数: $1" ``` 情况1:不加引号 ```bash ./test.sh hello world # 输出: # 参数个数: 2 # 第一个参数: hello ./test.sh "hello world" # 输出: # 参数个数: 1 # 第一个参数: hello world ``` 情况2:在脚本内部使用参数时加引号与不加引号的区别 假设我们有一个包含空格的参数,比如文件名"my file.txt"。 在脚本中: ```bash #!/bin/bash # 不加引号 for i in $1; do echo "不加引号: $i" done # 加引号 for i in "$1"; do echo "加引号: $i" done ``` 执行: ```bash ./test.sh "my file.txt" ``` 输出: ``` 不加引号: my 不加引号: file.txt 加引号: my file.txt ``` 可见,不加引号时,参数被拆分成两个单词,而加引号则保持为一个整体。 另外,对于特殊变量$@$*: - "$@":每个参数都被引号括起来,相当于"$1" "$2" ...,用于保留每个参数的原意,即使参数中包含空格。 - "$*":所有参数被合并成一个字符串,由IFS的第一个字符分隔(默认为空格),即"$1 $2 ..."。 - 不加引号时,$@$*的行为相同,都会进行单词拆分通配符扩展。 因此,在脚本中处理参数时,通常建议给变量加上双引号,以避免不必要的分词扩展。 总结: 在Shell脚本中,给参数扩展(如$1, $@等)加上双引号的作用是: 1. 防止单词拆分(word splitting),保留参数中的空格。 2. 防止通配符扩展(globbing),避免将*、?等当作通配符处理。 这样能够确保脚本在处理包含空格或特殊字符的参数时行为正确。 [^2] [^4]</think>在 Shell 脚本中,给参数扩展(如 `$1`, `$2`)加上引号的核心作用是 **防止单词拆分(word splitting)通配符扩展(globbing)**,确保参数值被当作一个整体处理。以下是具体分析: --- ### 一、不加引号的潜在问题 当参数值包含特殊字符(空格、制表符、通配符等)时,不加引号会导致意外行为: ```bash #!/bin/bash # test.sh echo "参数数量: $#" echo "第一个参数: $1" ``` **执行场景:** ```bash ./test.sh hello world # 正常:两个参数 ./test.sh "hello world" # 正常:一个参数(带空格) ./test.sh *.txt # 问题:通配符扩展为多个文件 ./test.sh "*.txt" # 正常:传递字面量 "*.txt" ``` --- ### 二、加引号的作用详解 #### 1. 防止单词拆分(Word Splitting) 当参数包含空格时,不加引号会被拆分为多个参数: ```bash # 不加引号(错误) file="My Document.txt" cat $file # 实际执行:cat My Document.txt → 报错 # 加双引号(正确) cat "$file" # 实际执行:cat "My Document.txt" ``` #### 2. 防止通配符扩展(Globbing) 当参数包含 `*`、`?` 等通配符时,不加引号会触发文件名扩展: ```bash # 不加引号(错误) arg="*.txt" echo $arg # 输出当前目录所有.txt文件 # 加双引号(正确) echo "$arg" # 输出 "*.txt" ``` #### 3. 保留特殊字符 引号能保护 `$`、`!` 等特殊字符不被解析: ```bash arg=&#39;$HOME&#39; echo $arg # 输出 /home/user(变量被展开) echo "$arg" # 输出 "$HOME" ``` --- ### 三、特殊变量 `$@` `$*` 的引号差异 | 语法 | 行为 | |------------|----------------------------------------------------------------------| | `$*` | 所有参数合并为单个字符串(空格分隔) | | `"$*"` | **所有参数作为单个字符串**(`IFS` 第一个字符分隔) | | `$@` | 所有参数作为独立字符串(但可能被拆分) | | `"$@"` | **所有参数保持原样独立传递**(最安全的参数传递方式)[^4] | **示例脚本:** ```bash #!/bin/bash # args.sh echo &#39;使用 "$@" :&#39; for arg in "$@"; do echo "[$arg]" done echo &#39;使用 "$*" :&#39; for arg in "$*"; do echo "[$arg]" done ``` **执行结果:** ```bash ./args.sh "a b" "c d" # 输出: # 使用 "$@" : # [a b] # [c d] # 使用 "$*" : # [a b c d] ``` --- ### 四、最佳实践总结 1. **始终用双引号包裹变量** ```bash cp "$source" "$dest" # 正确 cp $source $dest # 危险! ``` 2. **函数参数传递用 `"$@"`** ```bash process_args() { for arg in "$@"; do # 保留所有参数原样 ... done } ``` 3. **处理空变量更安全** ```bash [ -n "$var" ] # 即使 $var 为空也不会报错 ``` > 关键点:引号不是变量的一部分,而是控制 **Shell 如何解释变量内容** 的机制[^1][^3][^4]。 --- ### 相关问题 1. Shell 脚本中如何处理包含换行符的参数? 2. 为什么在 `[[ ]]` 条件测试中变量可以不加引号? 3. 单引号 `&#39;$var&#39;` 双引号 `"$var"` 在参数扩展中有何本质区别? 4. 如何安全地处理包含引号嵌套的参数(如 `He said "Hello"`)?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值